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

时间:2015-11-07 20:09:19

标签: go

我很难理解为什么这些规则与指针类型.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 个答案:

答案 0 :(得分:14)

  1. 如果您有*T,则可以调用接收方类型为*T的方法以及接收方类型为T的方法(您引用的段落,{{ 3}})。
  2. 如果您有TMethod Sets,则可以调用接收方类型为*T的方法以及接收方类型为T的方法,因为方法调用t.Meth()将等同于(&t).Meth()addressable)。
  3. 如果您有T并且无法寻址,则只能调用接收方类型为T而不是*T的方法。
  4. 如果您有一个界面II方法集中的部分或全部方法都是由*T的接收方提供的方法余数由具有T)接收器的方法提供,然后*T满足接口I,但T没有。*T。这是因为T的方法集包含public static int mapBasedFinder(int[] arr){ Map<Integer, Integer> values = new HashMap<Integer, Integer>(); int result = 0; for(int i=0; i<arr.length; i++){ int temp = arr[i]; if(values.containsKey(temp)) values.put(temp, values.get(temp)+1); else values.put(temp, 1); Map.Entry<Integer, Integer> maxEntry = null; for (Map.Entry<Integer, Integer> entry : values.entrySet()) { int key = entry.getKey(); if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) { maxEntry = entry; result = entry.getValue() * key; } } } return result; } ,但不是相反(再次回到第一点)。
  5. 简而言之,您可以使用指针接收器将值接收器和方法混合和匹配,并将它们与包含值和指针的变量一起使用,而不必担心哪个是哪个。两者都有效,语法也一样。但是,如果需要带有指针接收器的方法来满足接口,那么只有一个指针可以分配给接口 - 一个值不会有效。

答案 1 :(得分: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界面。