【问题标题】:Go pointer first assignmentGo 指针第一次赋值
【发布时间】:2016-06-24 18:11:55
【问题描述】:

当我在玩闭包时,我偶然发现了这种行为。我无法绕开它。

此代码 sn-p 有效:

func main(){
    var a string = "foo"
    var b *string
    var c string = "bar"
    b = &c

    fmt.Printf("%s %s\n", a, *b)

    a = "hello"
    *b = "world"

    fmt.Printf("%s %s\n", a, *b)
}

而这不是:

func main(){
    var a string = "foo"
    var b *string
    *b = "bar"

    fmt.Printf("%s %s\n", a, *b)

    a = "hello"
    *b = "world"

    fmt.Printf("%s %s\n", a, *b)
}

https://play.golang.org/p/NHw3X__Wtd

请比我聪明得多的人解释一下。

【问题讨论】:

  • 该视频解释了 C 指针,但该课程也适用于学习。 youtube.com/watch?v=mnXkiAKbUPg
  • 感谢您的视频。我知道它在 C 中是如何工作的,但我从来没有意识到它在 go 中是一样的。愚蠢的我。但是被引用对象的指针是新的。其实很合适。

标签: pointers go initialization


【解决方案1】:

如果您没有明确指定初始值,则每个变量都会初始化为其类型的zero value。所有指针类型的零值是nil,这意味着它(还)不指向任何东西。

您可以随时将地址(指针值)分配给指针类型的变量。但在你初始化你的指针变量(除了nil)之前,它没有指向任何东西,因此你不能将任何东西分配给它指向的地方(因为那是“无”)。

为了设置指向的值,首先对其进行初始化,以便它实际上指向您可以设置/更改的某个位置。此初始化可能是某个其他变量的地址(与指向类型相同的类型 - 称为 element 类型),或者是由内置函数返回的某个新分配的指向类型的零值的地址new()函数。

这一行

var b *string

只是创建了一个*string 类型的新变量b,但它没有指定任何初始值,所以b 将被初始化为nil。它不指向任何东西(或任何地方)。如果您尝试设置 pointed 值:

var b *string
*b = "bar"

您会遇到运行时恐慌:

panic: runtime error: invalid memory address or nil pointer dereference

为了能够设置 pointed 值,您需要使用非nil 指针值对其进行初始化,例如:

b = new(string)

在此之后,您现在可以设置指向的值:

*b = "world"

请注意,当您这样做时:

var b *string
var c string = "bar"
b = &c

这将创建一个*string 类型的变量b,它将获得零值nil。并创建一个string 类型的变量c,并用值"bar" 对其进行初始化。然后获取c 的地址并将其存储在指针变量b 中。现在,如果你修改b指向的值,那将“也”修改变量c的值,因为b指向c(或者更准确地说b存储@的内存地址987654350@ 是)。因此,如果在此之后您这样做:

*b = "world"

你打印c*b的值,两者都是"world"

fmt.Println(c, *b) // Prints "world world" 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-16
    • 2011-10-27
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    相关资源
    最近更新 更多