去指针优先分配 [英] Go pointer first assignment

查看:58
本文介绍了去指针优先分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我鬼混闭包时,我偶然发现了这种行为.我不能把头缠住它.

此代码段有效:

  func main(){var a string ="foo"var b *字符串var c string ="bar"b =& cfmt.Printf(%s%s \ n",a,* b)a =你好"* b =世界"fmt.Printf(%s%s \ n",a,* b)} 

而事实并非如此:

  func main(){var a string ="foo"var b *字符串* b =酒吧"fmt.Printf(%s%s \ n",a,* b)a =你好"* b =世界"fmt.Printf(%s%s \ n",a,* b)} 

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

有人能比我聪明吗?

解决方案

每个变量都初始化为零值(如果您未明确指定初始值).所有指针类型的零值为 nil ,这表示它尚未指向任何内容(尚未).

您可以随时为指针类型的变量分配地址(指针值).但是直到初始化指针变量(除 nil 以外的任何其他变量)之前,该变量都没有指向任何对象,因此您无法将任何内容分配给它指向的位置(因为这是无").

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

此行

  var b *字符串 

仅创建类型为 * string 的新变量 b ,但未指定任何初始值,因此将初始化 b 改为 nil .它不指向任何东西(或任何地方).如果您尝试设置指向的值:

  var b *字符串* b =酒吧" 

您会遇到运行时恐慌:

  panic:运行时错误:无效的内存地址或nil指针取消引用 

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

  b = new(字符串) 

此后,您现在可以设置目标值:

  * b =世界" 

请注意,当您这样做时:

  var b *字符串var c string ="bar"b =& c 

这将创建类型为 * string 的变量 b ,该变量将获得零值 nil .并创建类型为 string 的变量 c ,并使用值"bar" 对其进行初始化.然后,获取地址 c 并将其存储在指针变量 b 中.现在,在此之后,如果您修改 b 所指向的值,这将同时"修改变量 c 的值,因为 b 指向 c (或更准确地说, b 存储 c 所在的内存地址).因此,如果在此之后您这样做:

  * b =世界" 

同时打印 c * b 的值,它们都将是"world" :

  fmt.Println(c,* b)//打印世界世界" 

While I was fooling around with closures, I stumbled upon this behavior. I can't wrap my head around it.

This code snippet works:

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)
}

Whereas this does not:

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

Could someone much cleverer than me please explain.

解决方案

Each variable is initialized to the zero value of its type if you don't explicitly specify an initial value. Zero value for all pointer types is nil which means it does not point to anything (yet).

You may assign an address (pointer value) at any time to a variable of pointer type. But until you initialize your pointer variable (to anything other than nil), it points to nothing and thus you can't assign anything to where it points to (because that is "nothing").

In order to set the pointed value, initialize it first so it will actually point to somewhere which you can set/change. This initialization may be the address of some other variable (of the same type as the pointed type - called the element type), or the address of some newly allocated zero value of the pointed type returned by the builtin new() function.

This line

var b *string

just creates a new variable b of type *string, but it doesn't specify any initial value, so b will be initialized to nil. It does not point to anything (or to anywhere). If you attempt to set the pointed value:

var b *string
*b = "bar"

You get a runtime panic:

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

For you to be able to set the pointed value, you need to initialize it with a non-nil pointer value, e.g.:

b = new(string)

After this you can now set the pointed value:

*b = "world"

Note that when you do:

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

This creates a variable b of type *string which will get the zero value nil. And creates a variable c of type string, and initializes it with the value "bar". And after that takes the address of c and stores it in the pointer variable b. Now after this if you modify the value pointed by b, that will "also" modify the value of the variable c because b points to c (or more precisely b stores the memory address where c is). So if after this you do:

*b = "world"

And you print the value of both c and *b, both will be "world":

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

这篇关于去指针优先分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆