英文:
what's the difference between a method referenced by an asterisk and method that isn't in Golang?
问题
假设我有一个结构体,这个结构体有两个方法。其中一个方法使用了一个星号,另一个方法没有使用。
以下是理解这个例子的代码。
type object struct{
name string
age int
}
func (obj *object) methodOne{
// 做一些事情
}
func (obj object) methodTwo{
// 做一些事情
}
我知道指针的概念,但在这个例子中仍然不理解。
英文:
Let's suppose I have a struct, and this struct has 2 methods. one is written with an asterisk and the other one isn't.
Here is the code to understand the example.
type object struct{
name string
age int
}
func (obj *object) methodOne{
// do something
}
func (obj object) methodTwo{
// do something
}
I know about pointers, but still didn't understand the concept in this example.
答案1
得分: 2
根据文档所说:
func (s *MyStruct) pointerMethod() { } // 指针方法
func (s MyStruct) valueMethod() { } // 值方法
对于不习惯使用指针的程序员来说,这两个示例之间的区别可能会令人困惑,但实际情况非常简单。在为类型定义方法时,接收器(上述示例中的s
)的行为就像它是方法的参数一样。因此,将接收器定义为值还是指针是同一个问题,就像函数参数应该是值还是指针一样。有几个考虑因素。
首先,最重要的是,方法是否需要修改接收器?如果需要修改,接收器必须是指针。(切片和映射作为引用,所以它们的情况稍微复杂一些,但是例如要在方法中更改切片的长度,接收器仍然必须是指针。)在上面的示例中,如果pointerMethod
修改s
的字段,调用者将看到这些更改,但是valueMethod
是使用调用者参数的副本调用的(这就是传递值的定义),因此它所做的更改对调用者是不可见的。
其次是效率的考虑。如果接收器很大,比如一个大的结构体,使用指针接收器会更便宜。
接下来是一致性的考虑。如果类型的某些方法必须具有指针接收器,那么其余的方法也应该具有指针接收器,以便无论如何使用类型,方法集都是一致的。有关详细信息,请参阅有关方法集的部分。
对于基本类型、切片和小结构体等类型,值接收器非常便宜,因此除非方法的语义要求指针,否则值接收器是高效和清晰的。
英文:
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
> For programmers unaccustomed to pointers, the distinction between
> these two examples can be confusing, but the situation is actually
> very simple. When defining a method on a type, the receiver (s in the
> above examples) behaves exactly as if it were an argument to the
> method. Whether to define the receiver as a value or as a pointer is
> the same question, then, as whether a function argument should be a
> value or a pointer. There are several considerations.
>
> First, and most important, does the method need to modify the
> receiver? If it does, the receiver must be a pointer. (Slices and maps
> act as references, so their story is a little more subtle, but for
> instance to change the length of a slice in a method the receiver must
> still be a pointer.) In the examples above, if pointerMethod modifies
> the fields of s, the caller will see those changes, but valueMethod is
> called with a copy of the caller's argument (that's the definition of
> passing a value), so changes it makes will be invisible to the caller.
>
> Second is the consideration of efficiency. If the receiver is large, a
> big struct for instance, it will be much cheaper to use a pointer
> receiver.
>
> Next is consistency. If some of the methods of the type must have
> pointer receivers, the rest should too, so the method set is
> consistent regardless of how the type is used. See the section on
> method sets for details.
>
> For types such as basic types, slices, and small structs, a value
> receiver is very cheap so unless the semantics of the method requires
> a pointer, a value receiver is efficient and clear.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论