英文:
Interfaces and Pointers in Golang tour #55 and #57
问题
在这两个教程示例中,为什么一个带有指针接收器的方法在一个案例中满足接口,而在另一个案例中却不满足接口?
在示例#55中,类Vertex
不满足Abser
接口,因为方法Abs
仅针对*Vertex
定义,而不是Vertex
:
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)
}
错误消息是:
prog.go:22: cannot use v (type Vertex) as type Abser in assignment:
Vertex does not implement Abser (Abs method has pointer receiver)
但是在示例#57中,类MyError
满足error
接口,尽管Error()
是为*MyError
定义的,而不是MyError
:
type error interface {
Error() string
}
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
根据这个答案中的描述,似乎两者都应该正常工作,但教程演示了第一个示例失败。有什么区别?
英文:
In these two tutorial examples, why does a method with a pointer receiver satisfy an interface in one case but not the other?
In example #55 the class Vertex
doesn't satisfy the Abser
interface because method Abs
is only defined for *Vertex
and not Vertex
:
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)
}
The error message is:
prog.go:22: cannot use v (type Vertex) as type Abser in assignment:
Vertex does not implement Abser (Abs method has pointer receiver)
But in example #57, the class MyError
satisfies the error
interface ok even though Error()
is defined for *MyError
and not MyError
:
type error interface {
Error() string
}
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
From the description in this answer, it seems like both should work ok, but the tutorial demonstrates the first one failing. What's the difference?
答案1
得分: 6
在示例57中,错误被返回如下:
<!-- language-all: go -->
return &MyError{
time.Now(),
"it didn't work",
}
这将返回一个指向MyError结构体的指针。而*MyError
满足接口要求。
在示例55中也指出了这一点:
a = &v // a *Vertex implements Abser
// 在下一行中,v是一个Vertex(而不是*Vertex)
// 并且不满足Abser接口。
a = v
正如你所引用的答案中所说,当情况相反时(*MyStruct
类型将具有MyStruct
的所有方法)。
英文:
in example57, the error is returned as such:
<!-- language-all: go -->
return &MyError{
time.Now(),
"it didn't work",
}
this returns a pointer to the MyError struct. And *MyError
satisfies the interface.
In example55 this is also pointed out:
a = &v // a *Vertex implements Abser
// In the following line, v is a Vertex (not *Vertex)
// and does NOT implement Abser.
a = v
As it says in the answer you are referring to, the generation occurs when it's the other way around (*MyStruct
type will have all the methods MyStruct
has)
答案2
得分: 3
在第57行中,只有*MyError
满足error
。正如你所看到的,从run()
返回的值是*MyError
,而不是MyError
:
func run() error {
return &MyError{ // <<< 注意 '&'
time.Now(),
"it didn't work",
}
}
英文:
In #57 only *MyError
satisfies the error
. As you can see, the value returned from run()
is *MyError
, not MyError
:
func run() error {
return &MyError{ // <<< Notice the '&'.
time.Now(),
"it didn't work",
}
}
答案3
得分: 3
在#57中,它返回了指向我的错误的指针:
return &MyError{ //注意"&"符号,表示返回该结构体的地址/指针。
time.Now(),
"它没有工作",
}
英文:
In #57 it is returning a pointer to my Error:
return &MyError{ //notice the "&", that means return the address / pointer to that struct.
time.Now(),
"it didn't work",
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论