在effective Go的文档中,它声明:
正如我们在ByteSize中看到的那样,可以为任何命名类型定义方法 (指针除外......
type ByteSlice []byte
func (slice ByteSlice) Append(data []byte) []byte {
// Body exactly the same as above
}
然后继续提供一个指针作为接收器的例子:
func (p *ByteSlice) Append(data []byte) {
slice := *p
// Body as above, without the return.
*p = slice
}
这不矛盾吗?或者这是否意味着这是无效的:
type ByteSlice []byte
type Pb *ByteSlice
func (p Pb) Append(data []byte) []byte {
}
虽然它看起来就像一个typedef!
答案 0 :(得分:2)
命名指针类型可能会导致模糊不清:
type T int
func (t *T) Get() T {
return *t + 1
}
type P *T
func (p P) Get() T {
return *p + 2
}
func F() {
var v1 T
var v2 = &v1
var v3 P = &v1
fmt.Println(v1.Get(), v2.Get(), v3.Get())
}
在最后一种情况下(特别是v3
),根据当前规范,应该调用Get()
方法是不明确的。是的,没有理由不能定义方法解决方案,但是为已经有解决方案的东西添加到语言中还有一个细节。
答案 1 :(得分:2)
作为指针的命名类型与指向命名类型的指针不同。
这是语言参考所说的:
该参数部分必须声明一个参数,即接收器。 其类型必须为T或* T形式(可能使用括号) 其中T是类型名称。由T表示的类型称为接收器 基础类型;它不能是指针或接口类型,它必须是 在与方法相同的包中声明。
这很清楚:如果T表示指针类型,那么你不能将它用作方法接收器。
请注意此处引用的谨慎语言:短语“其类型必须为T或T *形式”是指方法接收器的语法级规范(即该类型的“形式”) 。这与短语“由T表示的类型”不同,它在谈论T名称的类型(即,类型“表示”)。