为什么我不能将类型的值分配给实现带有接收者类型指针的方法的接口

为什么我不能将类型的值分配给实现带有接收者类型指针的方法的接口

本文介绍了为什么我不能将类型的值分配给实现带有接收者类型指针的方法的接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Golang的世界里只有2天大的时间,正在经历去旅行.我忍不住注意到了一种特殊性,我似乎无法用适当的推理来达成共识.

I am 2-days old in the world of Golang, and going through the go tour. I couldn't help but notice a peculiarity which I cannot seem to be able to come at terms with a proper reasoning.

此代码运行良好:

package main
import (
    "fmt"
    "math"
)
type Vertex struct{
    X,Y float64
}
type Abser interface{
    Abs() float64
}
func (v Vertex) Abs() float64{ //method with value receiver argument
    return math.Sqrt(v.X*v.X+v.Y*v.Y)
}
func main(){
    var myVer Vertex = Vertex{3,4}
    var inter Abser
    inter = &myVer //assigning *Vertex type to inter
    fmt.Println(inter.Abs())
}

同时,以下代码显示错误:

Meanwhile, the following code shows an error:

package main
import (
    "fmt"
    "math"
)
type Vertex struct{
    X,Y float64
}
type Abser interface{
    Abs() float64
}
func (v *Vertex) Abs() float64{ //method with pointer receiver argument
    return math.Sqrt(v.X*v.X+v.Y*v.Y)
}
func main(){
    var myVer Vertex = Vertex{3,4}
    var inter Abser
    inter = myVer //assigning Vertex type to inter
    fmt.Println(inter.Abs())
}

错误是:

在进入本节之前,我可以理解Go的创建者已经放弃了诸如此类的繁琐符号

Until reaching this section of the tour, I could understand that the creators of Go have let-go of the cumbersome notations like

(& v).method2name()

(&v).method2name()

因此具有值接收器的方法可以与值和指针一起使用,反之亦然.

So that methods with value receivers can be used with both values and pointers, and vice versa.

在使用接口时,为什么该语言区分两者(值和指针)?如果可以在此处应用相同的引用/取消引用原则会更方便吗?

Why does the language discriminate between the two (value and pointer) when working with interfaces? Wouldn't it be more convenient if the same reference/dereference principles could apply here?

我希望我不要错过太明显的东西.谢谢!

I hope that I am not missing something too apparent.Thanks!

推荐答案

" Intro ++ to Go Interfaces "说明了此问题:

您需要类型的一致性.

" Go中的方法,接口和嵌入式类型":

  • 相应指针类型 * T 的方法集是具有接收者 * T T
  • 的所有方法的集合

    • The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T
      • 任何其他类型 T 的方法集由所有接收方类型为 T 的方法组成.
        • The method set of any other type T consists of all methods with receiver type T.
        • Karrot Kake 方法集 的6309> answer 详细也在 go Wiki 中:

          接口中存储的具体值不可寻址,就像 map 元素不可寻址一样.
          因此,当您在接口上调用方法时,该方法必须具有相同的接收器类型,或者必须与具体类型可以直接区分.

          The concrete value stored in an interface is not addressable, in the same way that a map element is not addressable.
          Therefore, when you call a method on an interface, it must either have an identical receiver type or it must be directly discernible from the concrete type.

          可以按照预期使用指针和值分别调用指针和值接收器方法.
          可以使用指针值调用值接收器方法,因为它们可以先被取消引用.
          不能使用值调用指针-接收器方法,因为存储在接口中的值没有地址.

          Pointer- and value-receiver methods can be called with pointers and values respectively, as you would expect.
          Value-receiver methods can be called with pointer values because they can be dereferenced first.
          Pointer-receiver methods cannot be called with values, however, because the value stored inside an interface has no address.

          (没有地址"实际上意味着它是不可寻址)

          ("has no address" means actually that it is not addressable)

          这篇关于为什么我不能将类型的值分配给实现带有接收者类型指针的方法的接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 19:33