值类型包括:所有integer、所有float、bool、string、数组和structure
引用类型包括:指针、slice、map、chan、interface
个人理解:引用类型存的就是指针
变量初始化变量初始化分为声明和赋值两部分
var b int // b = 0
fmt.Println(b==0) // true
b = 1
var p *int // p = nil
fmt.Println(p==nil) // true
p = &b
var s []int
fmt.Println(s==nil) // true
s = []int{b}
- 对于值类型,声明了但是未赋值时,其值是类型零值,可以看出值类型变量存的就是数据的值
- 对于引用类型,声明了但是未赋值时,其值是nil,指针存储数据指针,未赋值指针指向nil;
type Test struct{}
func main() {
var (
a = []int{1}
b = Test{}
)
fmt.Printf("a以值打印\t%v\n", a)
fmt.Printf("a以指针打印\t%p\n", a)
fmt.Printf("b以值打印\t%v\n", b)
fmt.Printf("b以指针打印\t%p\n", b)
}
// 输出
a以值打印 [1]
a以指针打印 0xc00001a040
b以值打印 {}
b以指针打印 %!p(main.Test={})
要注意的是:虽然slice、map、channel底层是由结构体实现,但是slice、map、channel类型变量并不是这些结构体的实体对象,而是一个指针
附上slice、map和channel 源码便于理解
slice
type slice struct {
array unsafe.Pointer //指针
len int //长度
cap int //容量
}
map
type hmap struct {
// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.
// 不带锁,非线程安全
count int // # live cells == size of map. Must be first (used by len() builtin)
flags uint8
B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
hash0 uint32 // hash seed
buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated)
extra *mapextra // optional fields
}
channel
type hchan struct {
qcount uint // total data in the queue
dataqsiz uint // size of the circular queue
buf unsafe.Pointer // points to an array of dataqsiz elements
elemsize uint16
closed uint32
elemtype *_type // element type
sendx uint // send index
recvx uint // receive index
recvq waitq // list of recv waiters
sendq waitq // list of send waiters
// lock protects all fields in hchan, as well as several
// fields in sudogs blocked on this channel.
//
// Do not change another G's status while holding this lock
// (in particular, do not ready a G), as this can deadlock
// with stack shrinking.
lock mutex
}