为什么我们需要使用*来修改基本数据类型的值而不是用户定义的结构的值?

时间:2014-04-07 11:02:34

标签: go

我是Go的新手并且在C中有一些经验。现在让我感到困惑的是为什么在下面的代码中,我们需要取消引用str来修改值,而不是chk.j

在结构的情况下,这里还发生了什么?

type test struct {
    i int
    j string
}

func main() {
    str := new(string)
    *str = "Need Astrik"
    chk := new(test)
    chk.i = 5
    chk.j = "Confused"
    fmt.Println("printing", chk.i, chk.j, *str)
}

2 个答案:

答案 0 :(得分:5)

请参阅规范中的Selectors section

  

选择器自动取消引用指向结构的指针。 如果x是指向结构的指针,x.y(*x).y 的简写;如果字段y也是指向结构的指针,x.y.z(*(*x).y).z的简写,依此类推。如果x包含*A类型的匿名字段,其中A也是结构类型,则x.f(*x.A).f的简写。

总结:结构的指针成员会自动解除引用。

对于作业,没有这样的快捷方式,所以分配指针与C中相同:

*p = value

对于结构x,其成员y是指针,您希望将其目标值分配给:

*x.y = value

如果x是指向结构的指针,则上面的表达式转换为

*((*x).y) = value

答案 1 :(得分:1)

new创建一个指针。如果要为指针指向的内容指定某些内容,则需要取消引用它。如果你没有用new创建你的值,你就不需要取消引用任何指针:

//without magic := so you actually see the types of things
  package main
import "fmt"

func main(){
    var s string = "Hello World"
    s = "hello"
    var sp (*string) = &s
    fmt.Println(s) //hello
    fmt.Println(*sp) //hello
    *sp = "world"
    fmt.Println(s) //world
    fmt.Println(*sp) //world
}

您不需要取消引用您的测试chk,因为.的行为与C中的->.相同,具体取决于您是在结构还是指针上使用它结构。