英文:
Why can't a method be defined both for a struct and its pointer?
问题
给定golang tour的第54张幻灯片中的设置:
type Abser interface {
Abs() float64
}
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
为什么方法不能同时为结构体和指向结构体的指针定义?即:
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
定义这个会产生以下错误:
prog.go:41: method redeclared: Vertex.Abs
method(*Vertex) func() float64
method(Vertex) func() float64
英文:
Given the setup in the 54th slide of the golang tour:
type Abser interface {
Abs() float64
}
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
Why can't a method also be defined for the struct as well as the pointer to the struct? That is:
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
Defining this gives the following error:
prog.go:41: method redeclared: Vertex.Abs
method(*Vertex) func() float64
method(Vertex) func() float64
答案1
得分: 11
它可以。只需在结构体上定义它,而不是指针。它将双向解析。
方法集
> 相应指针类型 *T 的方法集是所有具有接收器 *T 或 T 的方法的集合(也就是说,它还包含 T 的方法集)
尝试运行:http://play.golang.org/p/PsNUerVyqp
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := Vertex{5, 10}
v_ptr := &v
fmt.Println(v.Abs())
fmt.Println(v_ptr.Abs())
}
更新: 根据评论,我创建了一个额外的示例,实际上使用了 Abser
接口来说明值和指针都满足接口。
https://play.golang.org/p/Mls0d7_l4_t
英文:
It can. Just define it on the struct and not the pointer. It will resolve both ways
Method Sets
> The method set of the corresponding pointer type *T is the set of all
> methods with receiver *T or T (that is, it also contains the method
> set of T)
Try live: http://play.golang.org/p/PsNUerVyqp
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := Vertex{5, 10}
v_ptr := &v
fmt.Println(v.Abs())
fmt.Println(v_ptr.Abs())
}
Update: As per comments I have created an extra example that actually makes use of the Abser
interface to illustrate that both the value and the pointer satisfy the interface.
答案2
得分: 4
在考虑以下示例时:
type T U
func (t *T) M() int { return 1 }
var t T
...我们现在可以通过写入t.M()
来调用t
上的M()
,因为语言允许在其基础(非指针)类型的实例上调用具有指针接收器的方法,即它等同于(&t).M()
。
如果现在允许额外定义:
func (t T) M() int { return 2 }
...那么无法确定现在的t.M()
应该返回什么。
英文:
While considering for example:
type T U
func (t *T) M() int { return 1 }
var t T
...we can now invoke M()
on t
by writing t.M()
as the language permits to call a method with a pointer receiver even on its underlying (non pointer) typed instances, i.e. it becomes equivalent to (&t).M()
.
If it will be permitted to now additionaly define:
func (t T) M() int { return 2 }
...then there's no way to tell what is now t.M()
supposed to return.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论