首页 文章

Golang方法集(指针与值接收器)

提问于
浏览
3

我很难理解为什么这些规则与指针类型.vs的方法集相关联 . 值类型

有人可以解释一下原因(从界面表的角度来看)

(William Kennedy博客的片段)

Values          Methods Receivers
-----------------------------------------------
T               (t T)
*T              (t T) and (t *T)

Methods Receivers    Values
-----------------------------------------------
(t T)                 T and *T
(t *T)                *T

来自规范的片段

方法集

类型可以具有与其关联的方法集 . 接口类型的方法集是其接口 . 任何其他类型T的方法集由用接收器类型T声明的所有方法组成 . 相应指针类型* T的方法集是用receiver * T或T声明的所有方法的集合(也就是说,它还包含方法一套T) . 其他规则适用于包含匿名字段的结构,如结构类型一节中所述 . 任何其他类型都有一个空方法集 . 在方法集中,每个方法必须具有唯一的非空方法名称 .

类型的方法集确定类型实现的接口以及可以使用该类型的接收器调用的方法 .

2 回答

  • 11
    • 如果你有一个 *T ,你可以调用接收器类型为 *T 的方法,以及接收器类型为 T 的方法(你引用的段落,Method Sets) .

    • 如果你有一个 T 并且它是addressable你可以调用接收器类型为 *T 的方法以及接收器类型为 T 的方法,因为方法调用 t.Meth() 将等同于 (&t).Meth()Calls) .

    • 如果您有 T 并且它不可寻址,则只能调用接收器类型为 T 而不是 *T 的方法 .

    • 如果你有一个接口 I ,并且 I 方法集中的部分或全部方法是由 *T 接收器的方法提供的(其余部分由带有 T 接收器的方法提供),则 *T 满足接口 I ,但 T 没有 . 那是因为 *T 的方法集包含 T ,但不是相反(再次回到第一点) .

    简而言之,您可以使用指针接收器将值接收器和方法混合和匹配,并将它们与包含值和指针的变量一起使用,而不必担心哪个是哪个 . 两者都有效,语法也一样 . 但是,如果需要具有指针接收器的方法来满足接口,那么只有指针可以分配给接口 - 一个值将无效 .

  • 0

    这是你必须要的答案 .

    来自Golang FAQ:为什么T和* T有不同的方法集?来自Go Spec:任何其他命名类型T的方法集由接收器类型T的所有方法组成 . 相应指针类型T的方法集是具有接收器T或T的所有方法的集合(也就是说,它还包含T)的方法集 . 如果接口值包含指针* T,则方法调用可以通过取消引用指针来获取值,但是如果接口值包含值T,则方法调用没有用于获取指针的有用方法 . 即使在编译器可以将值的地址传递给方法的情况下,如果方法修改了值,则更改将在调用者中丢失 . 例如,如果bytes.Buffer的Write方法使用值接收器而不是指针,则此代码:var buf bytes.Buffer io.Copy(buf,os.Stdin)将标准输入复制到buf的副本中,而不是进入buf本身 . 这几乎不是理想的行为 .

    关于Golang接口引擎盖下 .

相关问题