当前位置: 首页 > 科技观察

intmake是不是关键字?

时间:2023-03-13 18:25:09 科技观察

本文转载自微信公众号《董泽润的技术笔记》,作者董泽润。转载本文请联系董泽润技术笔记公众号。这是一个新手问题。有多少人知道int不是关键字?make也不是关键字?我们知道每一种语言都有关键字和保留字,而go语言就是以关键字少而著称。breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar只有25种,也就是说,常用的make、cap、len都不是关键字,基本数据类型int、int64、float也不是。但是C语言中有很多关键字。make内置函数packagemainimport"fmt"funcmain(){make:=func()string{return"hijacked"}int:=make()//完全OK,变量'int'将beastringfmt。Println(int)//Prints"hijacked"}这段代码make变量是一个返回字符串的闭包,int变量类型是字符串。最后,该函数打印被劫持。显然这段代码是疯了,谁这样写谁会被打死,但是可以编译成功,而且如果想继续用make创建map,或者用int声明变量,都会报错报道。本质上make、cap、len都是go源码中的函数名,有点笼统。//Make内置函数定位并初始化类型对象//slice、map、orchan(仅)。和new一样,第一个参数是一个类型,不是//值。与new不同,make的返回类型是它的相同类型//参数,而不是指向它的指针。结果的规范取决于//类型://切片:大小指定长度。切片的容量//equaltoitslength.Asecondintegerargumentmaybeprovidedto//specifyadifferentcapacity;itmustbenosmallerthanthe//length.Forexample,make([]int,0,10)allocatesanunderlyingarray//ofsize10andreturnsasliceoflength0andcapacity10thatis//backedbythisunderlyingarray.//Map:Anemptymapisallocatedwithenoughspacetoholdthe//specifiednumberofelements.Thesizemaybeomitted,inwhichcase//asmallstartingsizeisallocated.//Channel:Thechannel'sbufferisinitializedwiththespecified//buffercapacity.Ifzero,orthesizeismitted,thechannelis//unbuffered.funcmake(tType,size...IntegerType)Typefunclen(vType)intfunccap(vType)上面的int是运行时的make、len、cap的函数定义可以看评论或者看builtin.go。make接受三种类型的参数:Map、Channel和Slice。返回值是T类型的,不像new返回的是指针*T,也就是说变量名使用make,只是main函数词法块中的一个普通局部变量。同时覆盖runtime的make函数名。上面说的Predeclaredidentifiers是make,那么int呢?Thetruthisthesame,these都是go预定义的标识符PredeclaredidentifiersTypes:boolbytecomplex64complex128errorfloat32float64intint8int16int32int64runestringuintuint8uint16uint32uint64uintptrConstants:truefalseiotaZerovalue:nilFunctions:appendcapclosecomplexcopydeleteimaglenmakenewpanicprintprintlnrealrecover其实这些都document在builtin.go,包括常见的整数类型,true,false,iota,nil以及常用的函数make,new,copy等。这些可能对应于其他语言中的关键字或保留字。从编译原理来看,identifiers和keywords关键字没有本质区别。它们都是令牌。官方告诉我们,这些预定义的标识符符号是在universeblock块中隐式定义的,所以我们可以直接使用。那么什么是宇宙块呢?Block="{"StatementList"}".StatementList={Statement";"}。除了上面的显示语句块,还有很多隐式语句块。要小心,因为很多时候变量影子是因为这个隐式的universe块包含了所有Go源文本。每个包都有一个包块,其中包含该包的所有Go源文本。每个包都有每个文件都有一个文件块,其中包含该文件中的所有Go源文本。每个文件都有一个文件块,其中包含该文件中的所有Go源文本。每个“if”、“for”和“switch”语句都被认为在它自己的隐式块中。“switch”或“select”语句中的每个子句都充当隐式块。switch或select语句中的每个子句都是一个隐式块。我们犯了一个错误,打到了最后一个,造成了可变阴影。那么问题来了,为什么go选择预定义标识符的方式,而不是直接定义为关键字呢?Go更喜欢通用块而不是关键字,因为可以在不破坏现有程序的情况下将声明添加到通用块