Types 如何在Go中强制转换为类型别名?
请参见 相关代码:Types 如何在Go中强制转换为类型别名?,types,casting,go,Types,Casting,Go,请参见 相关代码: type somethingFuncy func(int) bool func funcy(i int) bool { return i%2 == 0 } var a interface{} = funcy func main() { _ = a.(func(int) bool) // Works fmt.Println("Awesome -- apparently, literally specifying the func signat
type somethingFuncy func(int) bool
func funcy(i int) bool {
return i%2 == 0
}
var a interface{} = funcy
func main() {
_ = a.(func(int) bool) // Works
fmt.Println("Awesome -- apparently, literally specifying the func signature works.")
_ = a.(somethingFuncy) // Panics
fmt.Println("Darn -- doesn't get here. But somethingFuncy is the same signature as func(int) bool.")
}
第一个强制转换通过显式声明类型来工作。但第二个问题引发了恐慌。为什么?是否有一种干净的方法可以转换为较长的func签名?tl;博士
对于类型断言(您使用的),只有实际的类型才重要。所以
somethingFuncy
只等于somethingFuncy
,而不等于func(int)bool
解释
首先,这与铸造无关。围棋中没有演员。
有和
您正在处理一个类型断言,并假设相同的条件成立
至于类型转换。我在读你的问题时也犯了同样的错误,但事实上行为上有很大的不同
假设您有两种类型,例如int
和typemyint
。它们都是可兑换的
共享相同的基础类型(转换规则之一),因此这是有效的():
现在,假设a
不是类型int
,而是类型interface{}
():
编译器将告诉您:
无法将(类型接口{})转换为MyInt类型:需要类型断言
所以现在我们不再做转换,而是做断言。我们需要这样做():
现在我们的问题和你的问题一样。此断言因以下原因而失败:
panic:接口转换:接口是int,而不是main.MyInt
其原因在规范的附录中说明:
对于接口类型的表达式x和类型T
,主表达式x.(T)
断言x
不是nil
,并且x
中存储的值属于T
类型。符号
x.(T)
称为类型断言。
更准确地说,如果T
不是接口类型,x.(T)
断言
x
的类型与T
的类型相同
所以int
必须与MyInt
相同。国家规定
(除其他规则外):
如果两个命名类型的类型名源自相同的TypeSpec,则它们是相同的
由于int
和MyInt
有不同的声明(),它们不相等
断言失败了。当您将a
断言为int
时,断言有效。
所以你所做的是不可能的
奖金:
实际的检查会发生,它只是检查两种类型是否相同
同样,正如所料。为了完成nemo令人敬畏的回答,请注意,虽然您不能直接从给定动态类型(例如,
int
)的接口(例如,interface{}
)跳到另一种类型(例如,typemyint
),但您可以依次执行两个步骤:
- 断言变量的动态类型是您期望的类型李>
- 将该断言的结果转换为您选择的类型
下面是您的游乐场代码片段,稍作修改:我相信您需要的是类型别名。提案已被接受,应在Go 1.9中。即
TypeSpec=标识符[“=”]类型。
参考文献2017年更新: 使用Go 1.9中的类型断言,您只需在定义类型的位置添加
=
type somethingFuncy = func(int) bool
这告诉编译器,
somethingFuncy
是func(int)bool
的替代名称如果它们的类型名源自相同的类型规范,我无法理解。你能给我举个例子吗?谢谢。下面有一些例子。在回答中,我使用了MyInt
,它的类型是specMyInt
。因此,MyInt
等于MyInt
,但不等于type MySecondInt
,因为MySecondInt
不等于MyInt
(名称不同)。很好的解释。我正在考虑为从另一个包导入的结构创建别名。我只是在做类型TreeNode.Node
,但当结构成员,即节点.Left
被分配一个值/地址时,它给出了需要类型断言
错误。这个解释让我了解了如何实际使用别名,现在在将类型TreeNode tree.Node
更改为类型TreeNode=tree.Node
后,它可以正常工作。感谢您的详细解释。请注意,如果您这样做,您将无法向新类型添加函数,它将只是一个别名。您将得到一个恼人的无法在非本地类型上定义新方法的错误。或者至少当我尝试使用基于字符串的自定义类型时,我这样做了。旧注释是对旧答案的注释,但为了子孙后代:它现在完全可以工作了,您可以添加方法,这是我正在使用的一种模式,go1.15仍然会出错:无法在非本地类型上定义新方法somethingFuncy
不是funcy(I int)bool
的类型别名。这是一种全新的类型,定义为funcy(i int)bool
。这就像定义类型A结构{Foo string}
和类型B结构{Foo string}
一样。他们是不同的。
var a interface{} = int(10)
var b MyInt = MyInt(a)
var a interface{} = int(10)
var b MyInt = a.(MyInt)
type somethingFuncy = func(int) bool