如何在 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 signature works.")


    _ = a.(somethingFuncy)  // Panics


    fmt.Println("Darn -- doesn't get here. But somethingFuncy is the same signature as func(int) bool.")

}

通过显式声明类型,第一个强制转换有效。但第二个演员恐慌。为什么?有没有一种干净的方法可以转换为更长的 func 签名?


POPMUISE
浏览 287回答 3
3回答

慕哥6287543

对于类型断言(您使用的),只有实际类型很重要。所以somethingFuncy只等于somethingFuncy和不等于func(int) bool。解释首先,这与铸造无关。在 go 中没有铸造。有类型断言和类型转换。您正在处理类型断言并假设与类型转换相同的条件。我在阅读您的问题时犯了同样的错误,但实际上行为存在巨大差异。假设您有两种类型,例如int和type MyInt int。它们是可转换的,因为它们共享相同的基础类型(转换规则之一),所以这是有效的(play):var a int = 10 var b MyInt = MyInt(a)现在,假设a不是类型int而是类型interface{}(play):var a interface{} = int(10) var b MyInt = MyInt(a)编译器会告诉你:无法将 (type interface {}) 转换为 MyInt 类型:需要类型断言所以现在我们不再做转换而是断言。我们需要这样做(播放):var a interface{} = int(10) var b MyInt = a.(MyInt)现在我们遇到了与您的问题相同的问题。此断言因恐慌而失败:恐慌:接口转换:接口是int,而不是main.MyInt其原因在规范的类型断言部分中有说明:对于接口类型和类型的表达式 x T,主表达式x.(T) 断言x不是,nil并且存储在其中的值x是类型T。该符号 x.(T)称为类型断言。 更准确地说,如果T不是接口类型,x.(T)则断言 的动态类型x与类型相同T。所以int必须与 相同MyInt。类型标识的规则规定(除其他规则外):如果两个命名类型的类型名称源自相同的 TypeSpec,则它们是相同的。由于int并MyInt具有不同的声明(TypeSpecs),它们不相等并且断言失败。当您断言ato 时int,断言有效。所以你在做什么是不可能的。奖金:实际检查发生在这段代码中,它只是检查两种类型是否如预期的一样。

繁花不似锦

使用 Go 1.9 中的类型断言,您可以简单地添加=定义类型的位置。type somethingFuncy = func(int) bool这告诉编译器这somethingFuncy是func(int) bool.

慕后森

只是为了完成 nemo 很棒的答案,请注意,虽然您不能直接从interface{}给定动态类型(例如,int)的接口(ef, )跳转到另一种类型(例如,type MyInt int),但您可以一个接一个地执行两个步骤:断言变量的动态类型是您期望的;将该断言的结果转换为您选择的类型。请注意,由于底层类型,顾名思义,是dynamic,因此最好测试类型断言是成功还是失败。另一方面,类型转换的正确性是由编译器强制执行的。这是您的游乐场片段略有修改:http : //play.golang.org/p/FZv06Zf7xi
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go