我可以将int转换为float64,如下所示:
var a int = 10var b float64 = float64(a)
关于类型断言,有效 走 </跨度> states:’类型必须是 ()所持有的具体类型{ var a int = 10 FOO的(a)}
这会引起恐慌:界面转换:接口是int,而不是float64。
请注意 走 </跨度> 规格说:
’对于接口类型的表达式x和类型T,主要
您只能从接口类型键入断言到基础类型。在这种情况下 int 。然后你使用类型转换 int 至 float64
int
float64
这个句子 在Effective Go中似乎确实令人困惑。看起来作者当时正在思考结构。
关于规范中断言的章节 更清楚:
对于接口类型的表达式x和类型T的主表达式 表达 x。(T)断言x不是nil,而x中存储的值是 类型T.符号x。(T)称为类型断言。 更确切地说,如果T不是接口类型,则x。(T)断言 动态类型x与类型T相同。在这种情况下,T必须 实现x的(接口)类型;否则类型断言是 因为x不可能存储类型T的值,所以无效 T是接口类型,x。(T)断言x的动态类型 实现接口T.
对于接口类型的表达式x和类型T的主表达式 表达
x。(T)断言x不是nil,而x中存储的值是 类型T.符号x。(T)称为类型断言。
更确切地说,如果T不是接口类型,则x。(T)断言 动态类型x与类型T相同。在这种情况下,T必须 实现x的(接口)类型;否则类型断言是 因为x不可能存储类型T的值,所以无效 T是接口类型,x。(T)断言x的动态类型 实现接口T.
事实 你可以将你的int转换为浮点数 (反过来)并不意味着你可以断言他们是同一种类型。
类型必须是接口持有的具体类型,或者是第二种类型 的 接口 强> 键入值可以转换为
这基本上解释了 以下 :
package main import "fmt" type Stringer interface { String() } type Byter interface { Bytes() } type Stringbyter interface { Stringer Byter } type Polymorphic float64 func (p *Polymorphic) String() {} func (p *Polymorphic) Bytes() {} func main() { i := interface{}(new(Polymorphic)) if _, ok := i.(Stringer); ok { fmt.Println("i can be asserted to Stringer") } if _, ok := i.(Byter); ok { fmt.Println("i can be asserted to Byter") } if _, ok := i.(Stringbyter); ok { fmt.Println("i can be asserted to Stringbyter") } if _, ok := i.(*Polymorphic); ok { fmt.Println("i can be asserted to *Polymorphic") } if _, ok := i.(int); ok { fmt.Println("i can be asserted to int") // Never runs } }
断言 int 失败因为它是一个 的 具体 强> 类型(而不是接口类型)不是 *Polymorphic 本身。
*Polymorphic