英文:
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",
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论