Pointers Go指针、引用、取消引用的规则: 我对GoLang的新认识,来自德尔福,C++世界,当然,对这个语言非常兴奋,我认为这注定会成为“下一个大事件”。

Pointers Go指针、引用、取消引用的规则: 我对GoLang的新认识,来自德尔福,C++世界,当然,对这个语言非常兴奋,我认为这注定会成为“下一个大事件”。,pointers,reference,go,pass-by-reference,Pointers,Reference,Go,Pass By Reference,我试图弄清楚Go解析器和编译器是如何处理指针和引用的——似乎找不到任何地方有明确的规则 例如,在下面的代码示例中,返回类型*list.list和局部变量l都是指针类型,它们的声明中需要指针符号*,但它们在使用时不必取消引用:l.PushBack(i)。但在同一代码中,输入参数value*int64被声明为指针,必须取消引用才能正确使用:var i int64=*value/2 我假设这是因为 >清单>清单是一个引用类型,所以使用时的撤销是隐式的,而代码> It64/Cux>是一个值类型,必须像任

我试图弄清楚Go解析器和编译器是如何处理指针和引用的——似乎找不到任何地方有明确的规则

例如,在下面的代码示例中,返回类型
*list.list
和局部变量
l
都是指针类型,它们的声明中需要指针符号
*
,但它们在使用时不必取消引用:
l.PushBack(i)
。但在同一代码中,输入参数
value*int64
被声明为指针,必须取消引用才能正确使用:
var i int64=*value/2

我假设这是因为<> >清单>清单<代码>是一个引用类型,所以使用时的撤销是隐式的,而<>代码> It64/Cux>是一个值类型,必须像任何一个值类型的指针一样处理,例如在C++中:它必须被撤销。p> 让我感到困惑的是,尽管必须使用
*
*list.list
声明为指针类型,但在使用list实例时,不需要取消引用。这让我一开始很困惑。是“就这样”,还是我遗漏了什么

示例:

func GetFactors(value *int64) *list.List {

    l := list.New()

    l.PushBack(*value)

    var i int64 = *value / 2

    for ; i > 1; i-- {

        if *value%i == 0 {

            l.PushBack(i)

        }
    }

    return l

}

列表的所有方法都有
*List
接收器:()

在您的示例中,
l
属于
*List
类型,因此无需取消对它们的引用

相反,假设你有这样的东西:

type A struct{}
func (a  A) X() {
    fmt.Println("X")
}
func (a *A) Y() {
    fmt.Println("Y")
}
你可以写:

a := A{}
a.X()
a.Y() // == (&a).Y()
或者,您可以执行以下操作:

a := &A{}
a.X() // same like == (*a).X()
a.Y()
但它只适用于方法接收器。Go不会自动转换函数参数。鉴于这些功能:

func A(x *int) {
    fmt.Println(*x)
}
func B(y int) {
    fmt.Println(y)
}
这是无效的:

A(5)
你必须这样做:

var x int 
A(&x)
B(*y)
这也是无效的:

var y *int
B(y)
你必须这样做:

var x int 
A(&x)
B(*y)
与C#或Java不同,当谈到结构时,Go不区分引用类型和值类型。
*列表
是指针,
列表
不是指针。修改
列表上的字段只会修改本地副本。修改
*列表上的字段将修改所有“副本”。(因为它们不是副本……它们都指向内存中的同一个对象)


有些类型似乎隐藏了底层指针(就像一个切片包含一个指向数组的指针),但Go总是按值传递

不,围棋中没有Java愚蠢和种族歧视。相反,当您调用“成员”函数时,会自动取消指针引用。(这些函数的定义实际上是不一致的。)好的-这对我来说终于有了一些意义。我发现围棋有一个很大的学习曲线-它看起来像C/C++但它的行为不像它…我仍然有一些困惑-请看:我应该何时返回参考:*list.list和when is list.list一样好。我知道,如果我想修改一个值“就位”,那么我需要一个引用,但是例如在我的示例代码中,C++的返回值是列表。如果不是因为C++11中的新“移动语义”,它类似于C#()中的值与引用类型。在这种情况下,您肯定要使用
*List
。虽然
List
可能会起作用,但它只复制第一个元素。链接列表的其余部分将被共享,如果修改它,可能会导致一些奇怪的行为。学习C/C++之后的最佳方法可能是对指针系统不做任何假设。某些解引用的语言规范为,并定义何时进行隐式转换。e、 g.:“与选择器一样,对使用指针的值接收器的非接口方法的引用将自动取消对该指针的引用:pt.Mv相当于(*pt.Mv。“为什么go会隐式地将值转换为预期指针的方法接收器的指针?”?为什么不让编译器抱怨类型不匹配呢?作为围棋初学者,这种“有时选择性隐式转换”让我感到困惑。