考虑以下代码片段:
package main
import "fmt"
type Interface interface {
Fun()
}
type Int int
func (Int) Fun() {}
func main() {
var x interface{}
x = Int(42)
if _, ok := x.(int); !ok {
fmt.Println("type assertion fails")
}
// why do the lines below fail to compile?
var y Interface
y = Int(42)
if _, ok := y.(int); !ok {
fmt.Println("type assertion fails")
}
}
第一个类型断言按预期执行。然而,在第二种情况下,类型断言是在编译时执行的(换句话说,程序不编译(
不可能的类型断言:int不实现接口(缺少Fun方法(
我从阅读"Go编程语言"(第206页(中了解到,第二个代码段应该编译,类型转换应该在运行时失败。
这两个片段之间有什么区别吗;x
和y
不是都是接口类型(不同的接口(吗?为什么第二个在编译时失败
来自C++背景,这看起来非常像将static_assert
(编译时(和assert
(运行时(组合成一个单一类型的断言,这看起来有点奇怪。
来自规范:
更准确地说,如果T不是接口类型,则x。(T(断言x的动态类型与类型T相同。在这种情况下,T必须实现x的(接口(类型;否则类型断言是无效的,因为x不可能存储类型T的值。如果T是接口类型,则x(T(断言x的动态类型实现接口T。
https://golang.org/ref/spec#Type_assertions
因此,由于int
不是接口类型,预计它无法编译;并且它不实现CCD_ 6(Interface
(。