Golang教程中的第55和第57节讲解了接口和指针的使用。

huangapple go评论126阅读模式
英文:

Interfaces and Pointers in Golang tour #55 and #57

问题

在这两个教程示例中,为什么一个带有指针接收器的方法在一个案例中满足接口,而在另一个案例中却不满足接口?

示例#55中,类Vertex不满足Abser接口,因为方法Abs仅针对*Vertex定义,而不是Vertex

  1. type Abser interface {
  2. Abs() float64
  3. }
  4. type Vertex struct {
  5. X, Y float64
  6. }
  7. func (v *Vertex) Abs() float64 {
  8. return math.Sqrt(v.X*v.X + v.Y*v.Y)
  9. }

错误消息是:

  1. prog.go:22: cannot use v (type Vertex) as type Abser in assignment:
  2. Vertex does not implement Abser (Abs method has pointer receiver)

但是在示例#57中,类MyError满足error接口,尽管Error()是为*MyError定义的,而不是MyError

  1. type error interface {
  2. Error() string
  3. }
  4. type MyError struct {
  5. When time.Time
  6. What string
  7. }
  8. func (e *MyError) Error() string {
  9. return fmt.Sprintf("at %v, %s",
  10. e.When, e.What)
  11. }

根据这个答案中的描述,似乎两者都应该正常工作,但教程演示了第一个示例失败。有什么区别?

英文:

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:

  1. type Abser interface {
  2. Abs() float64
  3. }
  4. type Vertex struct {
  5. X, Y float64
  6. }
  7. func (v *Vertex) Abs() float64 {
  8. return math.Sqrt(v.X*v.X + v.Y*v.Y)
  9. }

The error message is:

  1. prog.go:22: cannot use v (type Vertex) as type Abser in assignment:
  2. 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:

  1. type error interface {
  2. Error() string
  3. }
  4. type MyError struct {
  5. When time.Time
  6. What string
  7. }
  8. func (e *MyError) Error() string {
  9. return fmt.Sprintf("at %v, %s",
  10. e.When, e.What)
  11. }

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 -->

  1. return &amp;MyError{
  2. time.Now(),
  3. "it didn't work",
  4. }

这将返回一个指向MyError结构体的指针。而*MyError满足接口要求。

在示例55中也指出了这一点:

  1. a = &amp;v // a *Vertex implements Abser
  2. // 在下一行中,v是一个Vertex(而不是*Vertex)
  3. // 并且不满足Abser接口。
  4. a = v

正如你所引用的答案中所说,当情况相反时(*MyStruct类型将具有MyStruct的所有方法)。

英文:

in example57, the error is returned as such:

<!-- language-all: go -->

  1. return &amp;MyError{
  2. time.Now(),
  3. &quot;it didn&#39;t work&quot;,
  4. }

this returns a pointer to the MyError struct. And *MyError satisfies the interface.

In example55 this is also pointed out:

  1. a = &amp;v // a *Vertex implements Abser
  2. // In the following line, v is a Vertex (not *Vertex)
  3. // and does NOT implement Abser.
  4. 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

  1. func run() error {
  2. return &MyError{ // <<< 注意 '&'
  3. time.Now(),
  4. "it didn't work",
  5. }
  6. }
英文:

In #57 only *MyError satisfies the error. As you can see, the value returned from run() is *MyError, not MyError:

  1. func run() error {
  2. return &amp;MyError{ // &lt;&lt;&lt; Notice the &#39;&amp;&#39;.
  3. time.Now(),
  4. &quot;it didn&#39;t work&quot;,
  5. }
  6. }

答案3

得分: 3

#57中,它返回了指向我的错误的指针:

  1. return &MyError{ //注意"&"符号,表示返回该结构体的地址/指针。
  2. time.Now(),
  3. "它没有工作",
  4. }
英文:

In #57 it is returning a pointer to my Error:

  1. return &amp;MyError{ //notice the &quot;&amp;&quot;, that means return the address / pointer to that struct.
  2. time.Now(),
  3. &quot;it didn&#39;t work&quot;,
  4. }

huangapple
  • 本文由 发表于 2014年7月14日 23:08:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/24739725.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定