大家好,我是站长polarisxu。有如下3行代码://32位机1)varxint32=32.02)varyint=x3)varzrune=x能编译出来吗?为什么?如果在面试的时候问这个问题,你需要想想面试官想考你什么。在进一步阅读之前,我建议您记下您的答案。01数字字面量在Go语言中,字面量是无类型的。无类型是什么意思?无类型意味着可分配给类似类型的变量或常量。使用上面的示例,32.0是一个无类型的浮点文字,因此它可以分配给任何与数字相关的类型变量(或常量)。以下都是合法的:varaint64=32.0varbint=32.0varcfloat32=32.0vardcomplex64=32.0varebyte=32.0varfrune=32.0所以上面问题中的1)是正确的。02类型不同在目前的Go1.16版本中(其实只有很早的版本不是),int类型在32位机器上占4个字节,在64位机器上占8个字节。因此,在32位机器上,int32和int的内存占用和内存布局是完全一样的。但是Go语言没有做隐式类型转换,int和int32是不同的类型,所以上面问题中的2)编译不通过。03类型别名熟悉C语言的会在Go中看到如下定义:typemyintint会认为myint和int是一样的,myint是int的别名。其实myint和int是完全不同的类型,但是myint的底层类型是int,它们可以直接转换,不能隐式转换。这个不用多说,重点是类型别名。从Go1.9开始,引入了类型别名,定义如下:AliasDecl=identifier,"=",Type。具体例子:typeintalias=intmyint是一种新类型,不同于int;虽然intalias与int相同,但它只是int的别名:Int可以在任何使用intalias的地方使用。那么为什么要在Go中引入类型别名呢?RussCox的论文代码库重构(在Go的帮助下)提供了相关背景知识。总结一下类型别名的用途,主要有两点:大规模重构项目代码时,尤其是将一个类型从一个包移动到另一个包时,有些代码会使用新包中的类型,而有些代码使用旧包中的类型,最典型的是上下文包。一开始context包名是golang.org/x/net/context。从1.7开始,引入了标准库,所以一共两份。Go1.9开始使用别名对其进行重构;允许一个大包分解成多个内部小包,但小包中的类型需要集中暴露在上层包中;在Go中,你可以为任何类型定义别名,比如数组、结构体、指针、函数、接口、Slices、Maps、Channels等,包括为自定义类型定义别名。typeF=func()typeI=interface{}...另外,还可以为其他包中的类型定义别名,比如为标准库类型定义别名:typeMyReader=bufio.Reader关于类型别名的一些注意事项:Alias和original类型相同,所以switch-type结构中不能有两种情况,一种是原始类型,一种是别名;类型别名不能循环定义,例如不允许这样:在原始类型或别名上定义;别名的可导出性可以不同于原始类型;您不能在另一个包的Add方法中为类型定义别名。不允许以下行为:typeMyReader=bufio.Readerfunc(MyReader)AliasMethod(){fmt.Println("Thisisalismethod")}编译错误:无法在非本地类型bufio.Reader上定义新方法。回到开头的3),符文的类型是什么?定义如下:typerune=int32显然,rune是int32的别名,所以题中的3)也可以编译。除了rune,在Go的内置类型中,byte是uint8的别名:typebyte=uint8需要注意的是,在Go1.9之前,rune和byte的别名是存在的,由编译器负责处理.只有在Go1.9之后,别名才能用于其他类型。04总结一道看似简单的题,如果你能分析透彻,说出所有的语言变化,相信面试官会给你加分的。今天的话题,你答对了吗?本文转载自微信公众号「polarisxu」,作者polaris。转载本文请联系polarisxu公众号。
