go变量初始化

var

var 关键字用于初始化变量(所有类型)并赋值,如果没有显示赋值,则隐式赋该类型的零值:

1
var name type [= value]

示例:

1
2
3
4
5
6
7
8
9
10
type User struct {
Name string
Age int
}
var i int // i = 0
var s string // s = ""
var b bool // b = false
var u1 User // u1 = {Name: "", Age: 0}
var u2 *User // u2 = nil 因为指针的零值就是nil
var ss []string // ss = [] 一个空的string类型的切片

使用var一般不会显式赋值,如果需要显式赋值,一般使用:=

1
s := "hello word"

new()

1
new(T)

T可以是任何类型,new(T)会初始化变量,并赋值变量T类型的零值,然后返回该变量的指针。

Tstring为例,模拟 new(string)

1
2
3
4
func newString() *string {
var s string
return &s
}
1
2
3
4
5
func main() {
s1 := new(string)
s2 := newString()
fmt.Println(*s1 == *s2) // true 都是空字符串的指针
}

make()

new(T)适合初始化值类型的变量,因为返回其指针,后续传递可以传递该指针,避免值拷贝。

new(T不适合初始化引用类型的变量,因为传递引用类型的变量没有值拷贝的问题。T是引用类型,则返回指针的指针,意义不大。

make() 用于初始化 slice、map 或 chan(只有这三种类型)的变量。

make([]T, len[, cap])

初始化 slice 类型的变量,指定 len 和 cap。

如果不指定 cap,则 cap 等于 len。

make(map[T1]T2)

初始化 map 类型的变量,不指定 len,更没有 cap。

make(chan T[, len])

channel 必须通过 make 创建,var c chan int 这种形式创建的是 nil channel,是不能用的,无论收发都会被堵塞。

1
2
3
4
5
// 无缓存channel
c := make(chan int)

// 有缓存channel
c := make(chan int, 3)

nil 切片与空切片

1
2
var s1 []int    // nil切片
s2 := []int{} // 空切片,或者用 make([]int,0)
  • nil 切片和空切片指向的地址不一样。nil 空切片引用数组指针地址为 0(无指向任何实际地址);
  • 空切片的引用数组指针地址是有的,且固定为一个值。