定位指针,引用,取消引用的规则: [英] Rule for Go Pointers, References, Dereferencing:
问题描述
我是GoLang的新手,来自Delphi C ++世界-诚然对这种语言感到非常兴奋,我认为它必将成为下一件大事".
I am new to GoLang, coming from the Delp C++ world - admittedly very excited about this language, which I think is destined to become "the next big thing".
我正试图了解Go解析器和编译器如何处理指针和引用-似乎找不到任何放置一些明确规则的地方.
I am trying to get a handle around how the Go parser and compiler handle pointers and references - can't seem to find any place where some clear rules are laid out.
例如,在下面的代码示例中,返回类型*list.List
和局部变量l
是指针类型,并且在其声明中需要指针符号*
,但是在使用时不必取消引用它们. :l.PushBack(i)
.但是在同一代码中,输入参数value *int64
被声明为指针,必须被取消引用才能正确使用:var i int64 = *value / 2
In the below code sample for example, the return type *list.List
and the local variable l
are pointer types and require the pointer symbol *
in their declarations, but they don't have to be dereferenced in use: l.PushBack(i)
. But in this same code the input parameter value *int64
is declared as a pointer and has to be dereferenced to be used properly: var i int64 = *value / 2
我认为这是因为list.List
是引用类型,所以在使用时取消引用是隐式的,而int64
是值类型,必须像对待值类型的任何指针一样进行处理,如C ++中那样示例:必须取消引用.
I assume that this is because list.List
is a reference type, so the dereferencing is implicit when used, while int64
is a value type and must be handled just as any pointer to a value type, as in C++ for example: It must be dereferenced.
令我困惑的是,即使必须使用*
将*list.List
声明为指针类型,使用列表实例时也不需要取消引用.一开始这让我很困惑.是就这样",还是我错过了什么?
What is confusing to me is that even though *list.List
has to be declared as a pointer type using *
, when using the list instance, dereferencing is not required. This had me quite confused initially. Is that "just the way it is", or am I missing something?
示例:
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
}
推荐答案
All of the methods for a List
have *List
receivers: (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{}
在您的示例中,l
的类型为*List
,因此无需取消引用它们.
In your example l
is of type *List
, so there's no need to dereference them.
相反,假设您有类似这样的内容:
Suppose, instead, that you had something like this:
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()
或者您可以执行以下操作:
Or you can do the following:
a := &A{}
a.X() // same like == (*a).X()
a.Y()
但是它仅适用于方法接收者. Go不会自动转换函数参数.具备以下功能:
But it only works for method receivers. Go will not automatically convert function arguments. Given these functions:
func A(x *int) {
fmt.Println(*x)
}
func B(y int) {
fmt.Println(y)
}
这是无效的:
A(5)
您必须这样做:
var x int
A(&x)
这也是无效的:
var y *int
B(y)
您必须这样做:
B(*y)
与C#或Java不同,当涉及到结构时,Go不会在引用类型和值类型之间进行区分. *List
是指针,List
不是指针.修改List
上的字段只会修改本地副本.修改*List
上的字段会修改所有副本". (因为它们不是副本...它们都指向内存中的同一件事)
Unlike C# or Java, when it comes to structs, Go does not make a distinction between reference and value types. A *List
is a pointer, a List
is not. Modifying a field on a List
only modifies the local copy. Modifying a field on a *List
modifies all "copies". (cause they aren't copies... they all point to the same thing in memory)
有些类型似乎隐藏了基础指针(例如切片包含指向数组的指针),但是Go总是按值传递.
There are types which seem to hide the underlying pointer (like a slice contains a pointer to an array), but Go is always pass by value.
这篇关于定位指针,引用,取消引用的规则:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!