Hello World
语法真的很简洁,Go 的包中的方法大多是大坨峰写法。
package main
import (
"fmt"
)
// 1. 运行:go rn example/01-hello/main.go
// 2. 编译为二进制:go build example/01-hello/main.go
// 执行二进制文件:./main
func main() {
fmt.Println("hello world")
}
变量和常量
变量
声明变量有两种写法
- 使用 var
// 直接赋值,等价于 var a string = "initial"
var a string = "initial"
// 声明类型,但其实 var 会根据值自动推断类型
var b, c int = 1, 2
// 直接赋值,等价于 var d bool = true
var d = true
// 如果不赋值,则需要声明类型,因为没有值,所以不能自动推断类型
var e float64
- 使用 :=
// 使用 := 代替 var,两种等价,推荐使用第一种
f := float32(e)
var f2 = float32(e) // 注意,Go 中如果声明了变量不使用会报错
g := a + "foo"
fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
fmt.Println(g) // initialapple
常量(后续增加内容)
常量使用 const,和 C/C++ 中一样。Go 中的常量没有固定类型,自动确定类型
const s string = "constant"
const h = 500000000
const i = 3e20 / h
fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
for、if、switch
for
Go 中没有 while,相当炸裂!使用下面的 for 代替 while
for {
fmt.Println("loop")
break
}
for 不写括号,j 是新定义的变量,因此使用 :=,当然也可以使用 var j = 7,但 := 更简洁
for j := 7; j < 9; j++ {
fmt.Println(j)
}
for i <= 3 {
fmt.Println(i)
i = i + 1
}
for ; i <= 3; i++ {
fmt.Println(i)
}
if
if 也是没有括号,而且可以先赋值,再判断,一行搞定,优雅!对了,当 fmt.Println() 中有多个参数时,默认会按空格隔开
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
switch
switch 中不用写 Java、C/C++ 中的 break,a 可以是任意值,包括结构体,还可以写成 2, 3 这样的列表
a := 2
switch a {
case 1:
fmt.Println("one")
case 2, 3:
fmt.Println("two or three")
default:
fmt.Println("other")
}
数组(固定大小)和切片(可扩容,常用)
数组
数组的声明看着有些不习惯,用惯了 Java 的 int[] nums = new int[10]
// 一维数组
var a [5]int
a[4] = 100
b := [5]int{1, 2, 3, 4, 5}
// 二维数组
var twoD [2][3]int
切片
这个切片类似 Java 中的 List,注意添加元素的写法,需要重新赋值给 s,因为数组扩容了,开了一个新的数组,s 中这个新数组,可以在参数中添加多个元素,太简洁了。
s := make([]string, 2)
s[0] = "a"
s[1] = "b"
s = append(s, "d")
s = append(s, "e", "f")
数组的深拷贝
c := make([]string, len(s))
copy(c, s)
fmt.Println(c) // [a b c d e f]
切片数组可以切片,类似于 Python。但是不能负数
fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5]) // [a b c d e],不包括下标 5
map
map 的声明方式也是相当炸裂,不过确实简洁。注意使用了 make,和前面的切片一样。map 的访问方式和 C/C++ 中一样,是数组的访问方式。注意,map 是不会排序的。
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m) // map[one:1 two:2]
fmt.Println(len(m)) // 2
fmt.Println(m["one"]) // 1
fmt.Println(m["unknown"]) // 0
判断 map 中是否存在某个 key。ok = 1 表示存在,ok = 0 表示不存在
r, ok := m["unknown"]
fmt.Println(r, ok) // 0 false
删除 key
delete(m, "one")
直接创建 map
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3)
遍历数组、map
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num) // index: 0 num: 2
}
}
fmt.Println(sum) // 9
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
for k := range m {
fmt.Println("key", k) // key a; key b
}