变量/常量
go语言的变量声明主要有两种形式,一种是通过var声明(常量也可通过const声明),如下所示:
var t bool //= true,省略后面的赋值时,变量会赋予默认值
//可单个声明,可分组为语法块
const (
x int = 12
f float32 = 1.2
s string = "hello"
)
注意当声明省略了基本类型的时候,会根据赋值进行类型推导
var i = 64 //int
还有一种是短变量声明,通过:=在类型明确的地方代替var,这里也用到了类型推导(const无法这样声明)
i := 12 //int
f := 12.3 //float64
c := 12 + 3i //complex128
类型转换的方法为T(v),例如f := float64(i)
流程控制语句
for
for有三种形式的循环
var sum int = 1
//形式一,有三个条件,与Java的形式区别不大
for i := 1; i < 10; i++ {
sum += i
}
//形式二,有一个条件,类似于Java中的while
for sum < 100 {
sum += sum
}
//形式三,没有条件,是一个无限循环
for {
sum += 1
}
if
if有两种形式
var x int = -3
//形式一,类似于Java中的if
if x < 0 {
x = -x
}
//形式二,在条件表达式前执行一个简单的语句,语句的变量作用域只在if/else内
if i := 3; i > 0 {
i = -i
} else {
//...
}
defer
defer会将后面跟的函数推迟到外层函数返回之后执行
注意事项:
- 推迟调用的函数会立即求值,最后被调用
- 被推迟的函数被压入一个栈中,故被调用的顺序为后进先出
fmt.Println("counting")
for i := 0; i < 3; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
/* 结果为
counting
done
2
1
0
*/
更多类型
指针
指针和C++类似
var x int = 13
var y *int = &x
fmt.Println(*y)
结构体
一组字段
type Vertex struct {
X int
Y int
}
v := Vertex{1, 2}
v := Vertex{X: 1} //结构体文法,未初始化的字段会隐式初始化
结构体指针可以直接通过隐式间接引用(同结构体直接访问字段,如p.X)
数组/切片
注意数组是固定数量的
var a [10]int
想要提供动态大小,就需要切片,切片类似于数组的引用,不存储任何数据,引用了底层的数组,切片有两种声明方式
primes := [6]int{1, 2, 3, 4, 5, 6}
var s1 []int = primes[:4] //方法一,通过数组切片获得
var s2 []int = {1, 2, 3, 4} //方法二,构建一个数组,同时构建一个引用他得切片
var s3 []int = make([]int, 4[, 5]) //方法三,通过make创建len(s3) = 4, cap(s3) = 5
通过func append(s []T, vs ..T) []T向切片追加元素
var s []int
s = append(s, 0)
s = append(s, 1, 2, 3, 4)
range
for循环的range形式可遍历切片或映射
var pow = []int{1, 2, 3, 4}
for i, v := range pow {
fmt.Printf("index is %v, value is %v\n", i, v)
}
//单独获取索引
for i := range pow {
fmt.Printf("index is %v\n", i)
}
映射
映射就是map,将键映射到值,有两种声明方式
var m map[string]int = make(map[string]int) //方式一,通过make创建
var m map[string]int = map[string]int{
"helllo": 1,
"world": 2
} //方式二,文法方式,可创建空映射
修改映射
//修改或添加元素
m[key] = elem
//获得元素
elem = m[key]
elem, ok = m[key]
//删除元素
delete(m, key)
函数闭包
我个人的理解是,一个函数(如func1)的返回值也是一个函数(如func2),同时返回的函数中(func2)引用了了外边函数定义的变量,例:
//内部返回的函数使用了left和right
func fibonacci() func() int {
left := 0
right := 1
return func() int {
cur := left
left = right
right += cur
return cur
}
}
func main() {
f := fibonacci()
//闭包使用过程中会改变所引用的变量,从而导致结果的不同
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}