类型(基础数据类型)
下面是 Go 支持的基本类型:
- bool
- 数字类型
- int8, int16, int32, int64, int
- uint8, uint16, uint32, uint64, uint
- float32, float64
- complex64, complex128
- byte
- rune
- string
1 有符号整型
int8:表示 8 位有符号整型
大小:8 位,8个比特位,8个bit是1个bytes,所以范围应该是2的8次方,因为要表示正负和0,第1个bit位要表示正负(0是负,1是正),只有7个bit位能用,还要减去0这个数字,因此范围是 2的7次方减1
范围:-128~127
int16:表示 16 位有符号整型
大小:16 位, 2的15次方减1
范围:-32768~32767
int32:表示 32 位有符号整型
大小:32 位
范围:-2147483648~2147483647
int64:表示 64 位有符号整型
大小:64 位
范围:-9223372036854775808~9223372036854775807
int:根据不同的底层平台(Underlying Platform),表示 32 或 64 位整型。除非对整型的大小有特定的需求,否则你通常应该使用 int 表示整型。
大小:在 32 位系统下是 32 位,而在 64 位系统下是 64 位。
补充:python中int是一个对象,对象不只包含数据类型还有方法,因此它占的内存空间很大,远不止int64,因此运行速度慢;在go中,如果追求极致,表示的数字范围如果足够,比如年龄、选择等,可以用int8,只占8个bit位。也可以用默认的int,现在基本都是int64。
2 无符号整型
uint8:表示 8 位无符号整型
大小:8 位,没有负数,但要减去0这个数字,因此范围是 2的8次方减1
范围:0~255
uint16:表示 16 位无符号整型
大小:16 位
范围:0~65535
uint32:表示 32 位无符号整型
大小:32 位
范围:0~4294967295
uint64:表示 64 位无符号整型
大小:64 位
范围:0~18446744073709551615
uint:根据不同的底层平台,表示 32 或 64 位无符号整型。
大小:在 32 位系统下是 32 位,而在 64 位系统下是 64 位。
3 浮点型
float32:32 位浮点数
float64:64 位浮点数
32或64 表示小数点后长度多少位,float64 是浮点数的默认类型
4 复数类型
complex64:实部和虚部都是 float32 类型的的复数。
complex128:实部和虚部都是 float64 类型的的复数。
内建函数 complex用于创建一个包含实部和虚部的复数。complex 函数的定义如下:
func complex(r, i FloatType) ComplexType
该函数的参数分别是实部和虚部,并返回一个复数类型。实部和虚部应该是相同类型,也就是 float32 或 float64。如果实部和虚部都是 float32 类型,则函数会返回一个 complex64 类型的复数。如果实部和虚部都是 float64 类型,则函数会返回一个 complex128 类型的复数。
还可以使用简短语法来创建复数:c := 6 + 7i
5 其他数字类型
byte 是 uint8 的别名,单引号包裹。
package main
import "fmt"
func main() {
//var num byte = 'a'
var num byte = 'A'
fmt.Println("the number is:", num)
}
该程序将输出:
the number is: 97
the number is: 65
// ascii码小写a对应97,大写A对应65
rune 是 int32 的别名,单引号包裹。
32个bit位,相当于4个bytes,正好unicode编码所有的象形文字4个bytes可以表示出来。在循环字符串时,要考虑字节的长度,如中文是3个bytes,“abc中国”是9个bytes,考虑用byte方式还是rune方式来循环。
byte与rune本质存的是unicode编码的数字,不管unicode还是gbk编码,前面128位都与ascii码兼容。
在学习字符串的时候,我们会详细讨论 byte 和 rune。
6 string 类型
在 Golang 中,字符串是字节的集合。如果你现在还不理解这个定义,也没有关系。我们可以暂且认为一个字符串就是由很多字符组成的。我们后面会在一个教程中深入学习字符串。 下面编写一个使用字符串的程序。
双引号包裹:
package main
import (
"fmt"
)
func main() {
first := "Naveen"
last := "Ramanathan"
name := first +" "+ last
fmt.Println("My name is",name)
}
上面程序中,first 赋值为字符串 “Naveen”,last 赋值为字符串 “Ramanathan”。+ 操作符可以用于拼接字符串。我们拼接了 first、空格和 last,并将其赋值给 name。上述程序将打印输出:
My name is Naveen Ramanathan
反引号包裹:反引号里面可以换行,可以嵌套双引号
package main
import "fmt"
func main() {
s1 := `"zell"
is
nb`
fmt.Println(s1)
}
上述程序将打印输出:
"zell"
is
nb
7 bool类型
bool 类型表示一个布尔值,值为 true 或者 false。
package main
import "fmt"
func main() {
a := true
b := false
fmt.Println("a:", a, "b:", b)
c := a && b
fmt.Println("c:", c)
d := a || b
fmt.Println("d:", d)
}
在上面的程序中,a 赋值为 true,b 赋值为 false。
c 赋值为 a && b。仅当 a 和 b 都为 true 时,操作符 && 才返回 true。因此,在这里 c 为 false。
当 a 或者 b 为 true 时,操作符 || 返回 true。在这里,由于 a 为 true,因此 d 也为 true。
8 数据类型默认值:
只定义不赋值时,数据类型都有初始默认值
数字类型是 0
字符串类型是 空字符串
布尔类型是 false
// 注意
python中所有数据类型都自带bool属性,比如0,空都是false
go中不同数据类型的空是不一样的,不能直接比较
9 类型转换
Go 有着非常严格的强类型特征。Go 没有自动类型提升或类型转换。我们通过一个例子说明这意味着什么。
package main
import (
"fmt"
)
func main() {
i := 55 //int
j := 67.8 //float64
sum := i + j //不允许 int + float64
fmt.Println(sum)
}
上面的代码在 C 语言中是完全合法的,然而在 Go 中,却是行不通的。i 的类型是 int ,而 j 的类型是 float64 ,我们正试图把两个不同类型的数相加,Go 不允许这样的操作。如果运行程序,你会得到 main.go:10: invalid operation: i + j (mismatched types int and float64)
。
要修复这个错误,i 和 j 应该是相同的类型。在这里,我们把 j 转换为 int 类型。把 v 转换为 T 类型的语法是 T(v)。
package main
import (
"fmt"
)
func main() {
i := 55 //int
j := 67.8 //float64
sum := i + int(j) //j is converted to int
fmt.Println(sum)
}
现在,当你运行上面的程序时,会看见输出 122
,把浮点型强制转为int类型,会自动去掉小数点后的数字。
如果把int类型转为浮点型,相加后会保留小数点后的数字。会看见输出 122.8
package main
import (
"fmt"
)
func main() {
i := 55 //int
j := 67.8 //float64
sum := float64(i) + int(j)
fmt.Println(sum)
}
赋值的情况也是如此。把一个变量赋值给另一个不同类型的变量,需要显式的类型转换。下面程序说明了这一点。
package main
import (
"fmt"
)
func main() {
i := 10
var j float64 = float64(i) // 若没有显式转换,该语句会报错
fmt.Println("j", j)
}
i 转换为 float64 类型,接下来赋值给 j。如果不进行类型转换,当你试图把 i 赋值给 j 时,编译器会抛出错误。