关于Go直接赋值的代码理解

关于go值传递参考这个:Golang 中直接赋值,是值传递还是地址传递?

关于Go的str

    var s string
    fmt.Printf("%p\n", &s)
    s = "aaa"
    fmt.Printf("%p\n", &s)
    s = "bbb"
    fmt.Printf("%p\n", &s)
    b := s
    fmt.Printf("%p", &b)

 

 Go的直接赋值,地址是会发生改变的,相比较Python是不一样的。Go的str底层是一个结构体:

在runtime\string.go中有这样的代码“

 

 从名字看出来这是一个私有的,不过也可以看到str的组成了,我们可以看另外一个结构体

在reflect\value.go中有这样的源码:

 

 字符和slice的底层表示都是一个结构体,而数据部分是一个指针。

对于一个字符来说,初始化的时候,指针也初始化了

对这个字符赋值,改变的是结构体中的指针,字符本身的地址没有发生改变;

对这个字符重新赋值,改变的也只是结构体中的指针。字符本身的地址没有发生改变。

因为go都是值传递,变量之间互相赋值,都会创造一块新空间,地址会发生改变。

slice同理。

如果你想通过结构体验证,你可以这样:

    var s string
    s = "abc"
    hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
    fmt.Println(hdr.Data, hdr.Len)
    fmt.Printf("%p\n", &s)
    s = "abcd"
    fmt.Println(hdr.Data, hdr.Len)
    fmt.Printf("%p\n", &s)

 

posted @ 2022-07-02 18:55  青花メ  阅读(123)  评论(0编辑  收藏  举报