Go指针规则,参考文献,解除引用:

Vec*_*tor 3 pointers reference pass-by-reference go

我是GoLang的新手,来自Delphi,C++世界 - 对这种语言非常兴奋,我认为注定要成为"下一个大事".

我试图解决Go解析器和编译器如何处理指针和引用 - 似乎找不到任何明确规则布局的地方.

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

我假设这是因为list.List是一个引用类型,因此解除引用在使用时是隐式的,int64而是一个值类型,必须像处理值类型的任何指针一样处理,例如在C++中:必须取消引用它.

让我感到困惑的是,即使*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

}
Run Code Online (Sandbox Code Playgroud)

Cal*_*leb 11

所有的方法List*List接收器:(http://golang.org/pkg/container/list/)

func (l *List) Back() *Element
func (l *List) Front() *Element
func (l *List) Init() *List
...
func (l *List) Remove(e *Element) interface{}
Run Code Online (Sandbox Code Playgroud)

在您的示例中l是类型*List,因此不需要取消引用它们.

相反,假设您有这样的事情:

type A struct{}
func (a  A) X() {
    fmt.Println("X")
}
func (a *A) Y() {
    fmt.Println("Y")
}
Run Code Online (Sandbox Code Playgroud)

你被允许写:

a := A{}
a.X()
a.Y() // == (&a).Y()
Run Code Online (Sandbox Code Playgroud)

或者您可以执行以下操作:

a := &A{}
a.X() // same like == (*a).X()
a.Y()
Run Code Online (Sandbox Code Playgroud)

但它只适用于方法接收器.Go不会自动转换函数参数.鉴于这些功能:

func A(x *int) {
    fmt.Println(*x)
}
func B(y int) {
    fmt.Println(y)
}
Run Code Online (Sandbox Code Playgroud)

这是无效的:

A(5)
Run Code Online (Sandbox Code Playgroud)

你必须这样做:

var x int 
A(&x)
Run Code Online (Sandbox Code Playgroud)

这也是无效的:

var y *int
B(y)
Run Code Online (Sandbox Code Playgroud)

你必须这样做:

B(*y)
Run Code Online (Sandbox Code Playgroud)

与C#或Java不同,当涉及到结构时,Go不区分引用和值类型.A *List是指针,A List不是.List仅修改字段会修改本地副本.修改字段*List会修改所有"副本".(因为它们不是副本......它们都指向内存中的同一个东西)

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