内容简介:本系列文章并不会关注语法使用层面,更关心可能在使用中会出现的问题、以及通过这些问题引起的一些思考。相信这个系列会成为很有价值的文章。本文只关注Go语言的基本类型:如整型、浮点型、常量相关的内容。字符串、数组和切片等高级类型会在下一篇文章中讲述。初始化顺序:当前包级别变量 -> 导入外部包的init() -> 当前包内的init() -> main()。通常可将一个包导入但是不使用的方式,初始化某些配置数据。
声明
本系列文章并不会关注语法使用层面,更关心可能在使用中会出现的问题、以及通过这些问题引起的一些思考。相信这个系列会成为很有价值的文章。
要点
本文只关注 Go 语言的基本类型:如整型、浮点型、常量相关的内容。字符串、数组和切片等高级类型会在下一篇文章中讲述。
包
初始化顺序:当前包级别变量 -> 导入外部包的init() -> 当前包内的init() -> main()。通常可将一个包导入但是不使用的方式,初始化某些配置数据。
下面这段代码会运行config包和model包下的init()方法:
import ( "cmdb-bg/cmd" _ "cmdb-bg/config" _ "cmdb-bg/model" )
零值
我们都知道,当我们仅仅声明一个变量、但未对其进行初始化的时候,Go会给每种变量类型赋一个零值:
- 整型:0
- 浮点型:0
- bool型:false
func main() { var a int var b float64 var c bool fmt.Println(a, b, c) // 0 0 false }
赋值与类型推断
如果你之前已经使用了":="对某个变量进行了声明与初始化,如果你想再次为这个变量进行重新赋值,切记不要加":"
func main() { a := 1 a := 2 fmt.Println(a) // 报错:no new variables on left side of := a = 2 // ok }
func main() { var a int = 1 for a >= 1 { a := 2 // 无限循环 a = 2 // 正常执行 a = a-2 fmt.Println(a) } }
Go中可以用如下方式高效交换两个变量的值:
func main() { a := 0 b := 1 a, b = b, a // 交换,不需要使用临时变量 fmt.Println(a, b) // 1, 0 }
- Go的new()返回的是一个地址,而不是值本身:
func main() { a := new(int) fmt.Println(a) // 0xc000016050 }
if赋值加判断复合语句的作用域:f的作用域会被限制在if大括号所包裹的代码块内。在if的外部并不能使用变量f:
func f1() error { if f, err := os.Open("abc"); err != nil { return err } fmt.Println(f) // 编译不通过: undefined: f } // 解决: func f1() error { f, err := os.Open("abc") if err != nil { return err } f.Close() // ok }
运算与类型转换
int和int32是不同类型,若要把int当成int32来使用,必须进行强制类型转换。其他类型同理。
类型断言的使用(暂作了解):
func main() { // a必须是空接口类型, 任何类型都是interface的实现类,当声明为interface{}时,可以赋值给他任意类型 var a interface{} a = 2; // 类型断言会返回两个值 v, ok := a.(int) // 如果变量a是断言的类型,ok为true,v为被断言变量的值。 // 否则ok为false,v为断言类型的零值 fmt.Println(v, ok) // 2 true }
如果进行算术运算之后发生了溢出,那么Go会直接丢掉溢出的高位部分。
所有基本类型的值都是可以比较的(整型、浮点型),其他高级类型的比较,一部分需要遵循一定规则,而一部分高级类型是禁止比较的。
不同数据类型不能直接做运算。不像其他语言,Go语言没有隐式类型转换。要想强制对不同类型做运算,必须进行显式的强制类型转换。转换成同一种类型之后,才能做运算:
func main() { var a int8 = 100 var b int16 = 100 fmt.Println(a + b) // invalid operation: a + b (mismatched types int8 and int16) fmt.Println(int16(a) + b) // ok }
在进行强制类型转换时需要注意:当整数值的类型的有效范围由宽变窄时,会截掉一定数量的高位二进制数。与这个类似的还有把一个浮点数类型的值转换为整数类型值时,浮点数类型的小数部分会被全部截断:
func main() { var a int16 = 428 //00000001 10101100 fmt.Println(int8(a)) // -84 // 截断高8位为:10101100。Go中用二进制补码表示数值。转成原码为为 11010100 即十进制-84 }
浮点数的精度有限,尽量不要做浮点数运算结果的比较:
func main() { var f float32 = 16777216 // 1 << 24 fmt.Println(f == f+1) // false var a float32 = 1.23 var b float32 = 1.25 fmt.Println(a-b) // -0.01999998 }
iota常量让用二进制位做标记更简单了。在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一:
const ( FlagUp Flags = 1 << iota // 第一种标记 FlagBroadcast // 第二种标记 FlagLoopback // 第三种标记 FlagPointToPoint // 第四种标记 FlagMulticast // 第五种标记 )
下篇预告
【Go语言踩坑系列(二)】字符串
以上所述就是小编给大家介绍的《【Go语言踩坑系列(一)】基本数据类型》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 编译型语言、解释型语言、静态类型语言、动态类型语言概念与区别
- Python 到底是强类型语言,还是弱类型语言?
- 6. Go 语言数据类型:字典与布尔类型
- 智能合约基础语言(五):Solidity变量类型:引用类型
- GO语言的接口类型
- 7. Go 语言数据类型:指针
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro CSS Techniques
Jeff Croft、Ian Lloyd、Dan Rubin / Apress / 2009-5-4 / GBP 31.49
Web Standards Creativity: Innovations in Web Design with CSS, DOM Scripting, and XHTML一起来看看 《Pro CSS Techniques》 这本书的介绍吧!