我正在使用“go1.10 darwin / amd64”从“gotour”工具学习golang。
以下案例:
package main
import "fmt"
type Myapi interface {
fun1() int
}
type MyintA struct {
val int
}
type MyintB int
func (v *MyintA)fun1() int {
return int(v.val) + 1
}
func (v *MyintB)fun1() int {
return int(*v) + 1
}
func main() {
var a Myapi
a = &MyintA{3}
fmt.Println(a)
a = &MyintB(2) // Need b:=MyintB(2); a=&b
fmt.Println(a)
}
编译错误是:
$ go run try.go
#command-line-arguments
./ try.go:27:9:不能取MyintB(2)的地址
为什么在这种情况下,接口变量可以直接从MyintA获取地址而不是MyintB?
答案 0 :(得分:5)
这是explained in the specification:
对于类型为T的操作数x,地址操作& x生成类型为* T到x的指针。操作数必须是可寻址的,即,变量,指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或者可寻址数组的数组索引操作。作为可寻址性要求的例外,x也可以是(可能带括号的)复合文字。如果x的评估会导致运行时恐慌,那么& x的评估也会这样做。
表达式MyintB(2)
是MyintB
类型的常量值。它不是变量或地址操作中允许的其他操作数之一。变量使用var
或short variable declaration声明。
表达式MyintA{3}
是composite literal。可寻址性要求的例外允许获取该操作数的地址。
按照评论建议获取指向MyintB的指针:
b := MyintB(2)
a = &b
问题在于地址运算符,而不是对接口变量的赋值。