golang 类型-----没有markdown真是闹腾@51cto

golang 类型-----没有markdown真是闹腾@51cto,第1张

概述1. 变量2. 命名3. 常量4. 基本类型5. 引用类型6. 类型转换7. 自定义类型 变量 Go语言有两种方式定义变量: var 关键字:= 短变量声明符 var关键字 var x int   //自动初始化为0var y = false   //自动推断为bool类型 和C语言不同,类型被放在变量名之后,并且在运行时,为了避免出现不可预测行为,内存分配器会初始化变量为二进制零
1.变量2.命名3.常量4.基本类型5.引用类型6.类型转换7.自定义类型
变量

Go语言有两种方式定义变量:

var关键字:=短变量声明符

var关键字

varxint//自动初始化为0vary=false//自动推断为bool类型

和C语言不同,类型被放在变量名之后,并且在运行时,为了避免出现不可预测行为,内存分配器会初始化变量为二进制零值。 如果显示初始化变量的值,可以省略变量类型,由编译器推断。

Go语言一次可以定义多个变量,并可以对其初始化成不同的类型,比如

varx,yint//相同类型多个变量vara,s=10010,"hellogo"//不同类型多个变量

按照Go语言的编码规范,建议以组的方式整理多行变量定义,比如:

var(x,yinta,"hellogo")

短变量声明符

在介绍词法的章节中已经看到过这种用法,比如:

x:=10010a,s:=10010,"hellogo"

这种方式很简单,但日常开发中新手经常犯下的一个错误,比如:

varx=10010funcmain(){println(&x,x)...x:="hellogo"//对全局变量重新定义并初始化println(&x,x)}

可想而知最终酿成的后果;为了正确使用这种简单的短变量声明方式,请遵循如下限制:

1.定义变量的同时,显示初始化2.不能提供数据类型3.只能在函数体内部使用4.函数体内不能使用短变量重复声明5.不能使用短变量声明这种方式来设置字段值6.不能使用nil初始化一个未指定类型的变量

思考下面的代码片段,输出结果是什么?


functest(){x:=1fmt.Println(x){fmt.Println(x)x=3x:=2fmt.Println(x)x=5}fmt.Println(x)}

如何检查你的代码中是否存在这样的声明?

# go tool vet -shadow yourfile.go

Go编译器会将未使用的局部变量当作错误,比如:

funcmain(){x:=1varaint//adeclaredandnotusedfmt.Println(x)}

那么思考一下下面的代码,会不会报错?

funcmain(){x:=1consta=10010//???fmt.Println(x)}

所以要记住函数体中存在未使用的常量,不会引发编译器报错;

常量

常量表示运行时恒定不变的值,由const关键字声明,常量值必须是在编译期可确定的字符、字符串、数字或布尔值。 声明常量的同时可以指定其常量类型,或者由Go编译器通过初始化值推断,如果显示指定其常量类型,那么就必须保证常量左右值类型一致。 必要时要做类型转换。并且右值不能超出常量类型的取值范围,否则会造成溢出错误。比如:

const(x,y=100,-10010bbyte=byte(x)//类型不一致需要做类型转换cuint8=uint8(y)//溢出)

思考:修改一下上面的代码,只进行声明而没有对其初始化和指定类型,结果会怎样?

const(x=100ysstring="hellogo"c)fmt.Printf("%T,%v\n",y,y)fmt.Printf("%T,c,c)

结论证明: 在常量组中如果不指定常量的类型和初始化值,则与上一行非空常量的右值相同常量值可以是Go编译器能计算出结果的表达式,如unsafe.Sizeof,len,cap,iota等。

枚举

Go语言没有明确上的定义枚举enum类型,不过可以通过iota关键字来实现一组递增常量的定义,比如:

const(_=iotaKB=1<<(10*iota)//1<<(10*1)MB//1<<(10*2)GB//1<<(10*3))

多常量定义中也可以使用iota,它们各自单独计算,确保常量组中每行常量的列数量相等即可,比如:

const(a,b=iota,iota*10//0,0*10c,d//1,1*10)

如果中断iota自增,需要显示恢复,且后续的常量值将按行序递增,比如:const(a=iotab//b=???c=100d//d=???e=iota//c=???f//f=???)

自增常量可以指定常量类型,甚至可以自定义类型,比如:const(ffloat=iota//指定常量类型)typecolorbyteconst(blackcolor=iota//自定义类型redblue)

常量VS变量

常量是“只读”属性变量在运行期分配内存,而常量是在编译期间直接展开,作为指令数据使用数字常量不会分配存储空间,不能像变量那样可以进行内存寻址

比如:

constx=10constybyte=x//相当于constybyte=100constaint=10//显示指定常量类型,编译器做强类型检查constbbyte=a//cannotusea(typeint)astypebyteinconstinitializer 基本类型

650) this.width=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="basetype.PNG" alt="wKioL1h-2srBJJ6oAAEgBgrOzv8521.png" src="https://s2.51cto.com/wyfs02/M02/8C/EE/wKioL1h-2srBJJ6oAAEgBgrOzv8521.png">


引用类型

特指slice,map和channel这三种预定义类型,他们具有比数字、数组等更复杂的存储结构; 引用类型的创建必须是用make函数来创建,因为除了分配内存之外,还有一系列属性需要初始化,比如指针,长度,甚至包括哈希分布,数据队列等。 而内置函数new只是按照指定类型长度分配零值内存,返回指针。比如:

p:=new(map[string]int)//new函数返回指针m:=*pm["go"]=1//panic:assignmenttoentryinnilmap(运行时) 自定义类型

使用关键字type可以定义用户自定义类型,包括基于基本数据类型创建,或者结构体和函数等类型,比如:typeflagsbyteconst(execflags=1<<iotawriteread)

与var、const类似,多个type定义也可以合并成组,比如:type(userstruct{namestringageint}ffunc(user))//自定义一组类型u:=user{"Tom",20}varsayf=func(suser){fmt.Println(s.name,s.age)}say(u)

自定义类型与基础类型相比,它们具有相同的数据结构,但它们不存在任何关系,除 *** 作符外,自定义类型不会继承基础类型的其它信息,它们属于完全不同的两种类型, 即它们之间不能做隐式转换,不能视为别名甚至不能用于比较表达式。比如:type(dataint)varddata=10varxint=d//cannotused(typedata)astypeintinassignmentprintln(x==d)//invalIDoperation:x==d(mismatchedtypesintanddata) 未命名类型

与有明确标志符的bool,int,string等类型相比,数组、切片、字典、通道等类型与具体元素类型或长度等属性有关,所以称作 未命名类型(unnamed type)。当然可以用type为其提供具体名称,将其改变为命名类型(named type)。具有相同声明的未命名类型视作同一类型,比如:

1.具有相同基类型的指针2.具有相同元素类型和长度的数组(array)3.具有相同元素类型的切片(slice)4.具有相同键值类型的字典(map)5.具有相同数据类型及 *** 作方向的通道(channel)6.具有相同字段序列(字段名、字段类型、标签以及字段顺序)的结构体(struct)7.具有相同签名(参数类型,参数顺序和返回值列表,不包括参数名)的函数(func)8.具有相同方法集(方法名、方法签名、不包括顺序)的接口(interface)

结构体的tag经常被初忽视,它也属于结构体类型组成的一部分,而不仅仅是元数据描述。

类型转换

类型转换在日常开发中是不可避免的问题,Go语言属于强类型语言,除常量、别名以及未命名类型之外,其它不同类型之间的转换都需要显示类型转换;好处是我们至少能知道语句及表达式的确切含义,比如:a:=10//intb:=byte(a)//bytec:=a+int(b)//确保类型一致性d:=b+byte(a)//确保类型一致性

如果类型转换的目标是指针、单向通道、没有返回值的函数类型,那么为了避免语法歧义带来的类型转换错误,必须使用括号,比如:


x:=100p:=*int(&x)//cannotconvert&x(type*int)totypeint//invalidindirectofint(&x)(typeint)pc:=<-chanint(c)//invalIDoperation:pc<-3(sendtonon-chantypeint)

正确做法如下:

p:=(*int)(&x)//(*int)(&x)(<-chanint)(c)//单向通道(func())(f)//无返回值的函数(func()int)(f)//有返回值的函数,但是也可以不用括号:func()int(f),但是为了影响程序可读性,建议加上括号 总结

以上是内存溢出为你收集整理的golang 类型-----没有markdown真是闹腾@51cto全部内容,希望文章能够帮你解决golang 类型-----没有markdown真是闹腾@51cto所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1280344.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存