整数
- 有符号整数
int
,无符号整数uint
,且有9、16、32、64位版本 rune
类型表示一个Unicode码,其是int32
的同义词byte
是uint8
的同义词,强调是一个原始数据,而非量值uintptr
是能完整存放指针的类型
其算数运算与C++并无区别
无符号整数往往只用于位运算和特定算数运算符,如解析二进制格式文件,或者散列与加密。这与C++不同,就像返回数组长度的len()
返回有符号数一样
fmt.Printf()
输出数字的用法和printf()
也没有区别
浮点数
float32
,有效数字大约6位float64
,有效数字大约15位,为避免数值运算的误差应尽量使用这个- 特殊数值
math.Inf(1)
表示正无穷,可以使用1/0
得到math.Inf(-1)
表示负无穷,可以使用-1/0
得到math.NaN()
表示NaN,可以使用0/0
得到
复数
complex64
和complex128
分别由float32
和float64
构成- 内置函数
complex(real,imag)
传入实部和虚部,构造一个复数出来real()
返回实部,imag()
返回虚部
- 复数可以直接写成带i的字面值
x := 1+2i
布尔值
只有两个值,true
和false
,其它性质在任何编程语言中都一样,无需赘言
字符串
- 字符串是不可变的字节序列
- 这样
s[0] = 'L'
将是不可行的 - 不可变保证了两个字符串可以安全的共用同一段底层内存,减少了内存开销
- 这样
- 文本字符串是UTF8编码
- 字符串运算
len(s)
给出字符串的字节数s[i]
,总是取的是字节- 可以使用比较运算符比较字符串,像C++一样,是按位进行比较,字典序排序
- 可以使用
+
将一个字符串附加到另一个 s[i:j]
返回一个新字符串,其范围是原字符串的左闭右开区间
字符串字面量
- 使用双引号包裹的,就是我们熟悉的字符串字面量,且可以使用
\
表示转义 - 使用反引号
``
包裹的,称为原生字符串字面量,其内容不受转义序列影响,严格一致
UTF-8
UTF-8是以字节为单位对Unicode做变长编码。每个文字符号使用1~4个字节表示,ASCII字符占据一个字节。
变长编码,遍历字符串的方式
- 使用包
unicode/utf8
中的utf8.DecodeRuneInString
for i:=0; i<len(s); { r,size := utf8.DecodeRuneInString(s[i:]) fmt.Printf("%d \t %c \n ",i,r) i += size }
- 每次返回当前字符
r
和该字符占的字节大小
- 每次返回当前字符
- 使用
range
for i,r := range "Hello,世界"{ fmt.Printf("%d\t%q\n",i,r)
字符串和字节slice
通过对字符串强制类型转换成[]byte
来进行解码和解码后的操作
s := "abc"
b := []byte(s)
s2 := string(b)
常量
编译时期确定值,可以一次申请多个
const (
e = 2.718281828459
pi = 3.14159265358979323846264338327950288
)
一组常量,如果省略的话,沿用上一个常量的声明(类型或表达式)
const (
a = 1
b
)
这里的b沿用上一项,所以也是1
对于常量的操作,其结果仍然是常量
常量生成器itoa
有点类似枚举,使用iota
创建一系列的相关值,不用逐个写出。iota
自动从0逐项增加1
比如经常使用的,使用2的连续次幂的枚举量
const (
_ = 1<<(10*iota)
KiB
MiB
GiB
)
无类型常量
不属于任何具体的基本类型,但可以自动转换为任何类型。无类型常量是通过在常量声明时省略类型或者使用特定的语法来创建的。好处是可以暂时保有远超变量的精度