枚举
枚举指一系列的相关的常量,比如下面关于一个星期的中每天的定义,通过上篇博文,我们可以用在const后跟一对圆括号的方式定义一组常量,这种定义法在go语言中通常用于定义枚举值。go语言并不支持众多其他语言明确支持的enum关键字。
下面是一个常规的枚举表示法,其中定义了一系列整型常量。
const ( Sunday = iota Monday Tuesday Wednesday Thursday Friday Saturday numberOfDays // 这个常量没有导出 )
同go语言中的其他符号(symbol)一样,以大写字母开头的常量在包外可见。
以上列子中 numberOfDays为包内私有,其他符号则可被其他包访问。
数据基本类型
布尔类型: bool 整数类型: int8、byte、int6、int、uint、uintptr等。 浮点类型: float32、float64。 复数类型:complex64、complex128。 字符串:string。 字符类型:rune。 错误类型:error。 处上之外,go语言还支持一下的复合类型。 指针(pointer) 数组(array) 切片(slice) 字典(map) 通道(chan) 结构体(struct) 接口(interface)
上述类型的特点在于使用方便,但使用者不能对这些类型的长度做任何假设。对于常规的开发来说,用int和uint就可以了,没必要用int8之类明确指定长度的类型 ,以免导致移植困难。
布尔类型
go语言中的布尔类型与其他语言基本一致,关键字也是 bool ,可赋值为预定义的true和false。
var test bool test = true test_two := (1 == 2) // test_two也会被推导为bool类型 PS: 布尔类型不能接受其他类型赋值,不支持自动或强制的类型转换。 下面一些错误的语法: var a bool a = 1 // 语法错误 a = bool(1) // 语法错误 以下的用法才是正确: var one bool one = (1 != 0) // 正确语法 fmt.Println("result:", one) // go的输出 Println 输出结果: result : true
整型:
整型是所有语言里最基础的类型了。
类型 长度 值范围 int8 1 -128 ~ 127 uint8(既byte) 1 0 ~255 int16 2 -32 768 ~ 32 767 uint16 2 0~65 535 int32 4 -2 147 483 648 ~ 2 147 483 647 uint32 4 0 ~ 4 294 967 295 int64 8 -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807 uint64 8 0 ~ 18 446 744 073 709 551 615 int 因平台而定 因平台而定 uint 因平台而定 因平台而定 uintptr 同指针 在32位平台下为4字节,64位平台下为8字节
①、类型表示
需要注意的是,int和int32在go语言里被认为是两种不同的类型,编译器也不会帮你自动做转换类型,比如以下的列子会有编译错误:
var value2 int32 value1 := 64 // value1将会被自动推导为int类型 value2 = value1 // 编译错误 编译错误类似于: cannot use valu1 (type int) as type int32 in assignment。 使用强制类型转换可以解决这个编译错误: value2 = int32 (value1) //编译通过
当然,开发者在做强制类型转换时,需要注意数据长度被截断而发生的数据精度损失(比如将浮点数强制转为整数)和值溢出(值超过转换的目标类型的值范围时)问题。
②、数值运算
go语言支持下面的常规整数运算: +、-、*、/、和%。加减乘除就不解释了,需要说下的是,%和C语言中一样是求余运算,比如:
5 % 3 // 结果: 2
③、比较运算
go语言支持以下的几种比较运算符: > 、 < 、 ==、>=、 <=和!=。这一点与其他大多数的语言相通,与C语言完全一致。
④、运算符
运算 含义 样 列 x << y 左移 124 << 2 // 结果为496 x >> y 右移 124 >> 2 // 结果为31 x ^ y 异或 124 ^ 2 // 结果为126 x & y 与 124 & 2 // 结果为0 x | y 或 124 | 2 // 结果为126 ^x 取反 ^2 // 结果为3
go语言的大多数位运算符与C语言都比较类似,除了取反在C语言中是~x,而在go语言中是^x。
浮点型
浮点型用于表示包含小数点的数据,比如1.234就是一个浮点型数据,在go语言中的浮点类型采用IEEE-754标准的表达方式。
①、浮点数表示
go语言定义了两个类型float32和float64,其中float32等价于C语言的float类型,float64等价于C语言的double类型。
在go语言中,定义一个浮点数变量的代码如下:
var fvalue1 float32 fvalue1 = 12 fvalue2 := 12.0 // 如果不加小数点,fvalue2会被推导为整型而不是浮点型
对于以上列子类型被自动推导的fvalue2,需要注意的是其类型将被自动设为float64,而不管赋给它的数字是否使用32位长度表示的,因此,对于以上列子,下面的赋值将导致编译错误:
fvalue1 = fvalue2 而必须使用这样的强制类型转换: fvalue1 = float32(fvalue2)
②、浮点数比较
因为浮点数不是一种精确的表达方式,所以像整型那样直接用==来判断两个浮点数是否相等是不可行的,这可能会导致 不稳定的结果 。
下面是一种推荐的替代方案。import "mat// p为用户自定义的比较精度, 比如:0.00001
func IsEqual(f1, f2, p float64) bool { return math.Fdim(f1, f2) < p }
复数类型
复数实际上由两个实数(在计算机中用浮点数表示)构成,一个表示 实部(real),一个表示虚部(imag),如果了解了数学上的复数是怎么回事,那么go语言的复数就非常容易理解了。
①、复数表示
复数示例:
var value1 complex64 // 由2个float32构成复数类型 value1 = 3.2 + 12i value2 := 3.2 + 12i //value2是complex128类型 value3 := complex(3.2, 12) //value3结果同value2
②、实部与虚部
对于一个复数z = complex(x, y),就可以通过go语言内置函数real(z)获得该复数的实部,也就是x,通过imag(z)获得该复数的虚部,也就是y。
字符串
在go语言中,字符串也是一种基本类型,相比之下,C/C++语言中并不存在原生的字符串类型,通常使用字符数组来表示,并以字符指针来传递。
go语言中一下是字符串的声明和初始化。
var str string // 声明一个字符串变量 str = "Hello world" // 字符串赋值 ch := str[0] // 取字符串的第一个字符 fmt.Printf("The length of \"%s\" is %d \n", str, len(str)) fmt.Printf("The first character of \" %s\"is %c.\n", str, ch) 输出结果: The length of "Hello world" is 11 The first character of "Helllo world" is H.
字符串的内容看可以用类似于数组下标的方式获取,但与数组不同,字符串的内容不能再初始化后被修改,比如一下列子:
str := "Hello world" // 字符串也支持声明时进行初始化的做法 str[0] = "x" // 编译错误 编译器会报类似如下错误: cannot assign to str[0]
字符串的操作
运算 含义 样列 x + y 字符串连接 "Hello" + "123" // hello123 len(str) 字符串长度 len("hello") // 5 s[*] 取字符 "hello" [1] // e 更多方法请参考string标准库包!!!
①字符串遍历
go语言中支持两种遍历方式,一种是以字节数组的方式遍历:
str := "Hello,世界" n := len(str) for i := 0; i < n; i++ { ch := str[i] // 依据下标取字符串中的字符,类型为byte fmt.Println(i, ch) } 结果: 0 72 1 101 2 108 3 108 4 111 5 44 6 32 7 228 8 184 9 150 10 231 11 149 12 140
可以看出,这个字符串长度为13,尽管从直观上来说,这个字符串应该只有9个字符,这是因为每个中文字符在UTF-8中占三个字节,而不是壹个字节。
另一种是以Unicode字符遍历:
str := "Hello, 世界" for i, ch := range str { fmt.Println(i, ch) // ch的类型为true } 结果: 0 72 1 101 2 108 3 108 4 111 5 44 6 32 7 19990 10 30028
以Unicode字符方式遍历时,每个字符的类型是rune(早期的go语言用int类型表示Unicode字符),而不是byte。
字符类型
在go语言中支持两个字符类型,一个是byte(实际上是uint8的别名),代表UTF-8字符串的单个字节的值,另一个是rune,代表单个Unicode字符。