Go 的数据类型分四大类:基础类型(basic type)、聚和类型(aggregate type)、引用类型(reference type)和接口类型(interface type).
基本类型包括数字,字符串和布尔型。
整数类型:int8, int16, int32, int64 和 uint8, uint16, uint32, uint64。
取模运算符 % 的行为因编程语言而异。就 Go 而言,取模余数的正负号总是和被除数一致。
x := int64(0xdeadbeef)
fmt.Printf("%d %[1]x %#[1]x %#[1]X\n", x)
%后的副词[1]告知 Printf 重复使用第一个操作数。#告知输出相应的前缀 0, 0x 或 0X。
%q 输出带有单引号的文字符号。
%e(指数)输出,%f(无指数)输出,都可以控制宽度和精度 %8.3f.
Nan 的比较总是不成立(除了 !=, 它总是和 == 相反)
nan := math.NaN()
fmt.Println(nan == nan, nan < nan, nan > nan) // false, false, false
一个函数的返回值是浮点型且有可能出错,最好单独报错。
func compute() (value float64, ok bool) {
if failed {
return 0, false
}
return result, true
}
complex64 和 complex128,二者分别由 float32 和 float64 构成。而内置的 real和 imag 函数分别提取复数的实部和虚部。
bool 只有两种可能:true 和 false.
bool 运算可能短路。
字符串是不可变的字节序列,它可以包含任意数据,包括0值字节。
不可改变意味着两个字符串能安全的公用一段底层内存,使得复制任何长度字符串的开销都低。
原生的字符串字面量的书写形式是…
,使用反引号而不是双引号。原生的字符串字面量内,转义序列不起作用;实质内容和字面写法严格一致,包括反斜杠和换行符。因此,在程序源码中,原生的字符串字面量可以展开多行。唯一的特除处理时回车符会被删除(换行符会保留)。
const GoUsage = `Go is a tool for
Usage:
go command [arguments]
...`
Unicode 囊括了世界上所有文书体系的全部字符。在go 的术语中,这些字符记号成为文字符号(rune)。rune 类型作为 int32 类型的别名。
当 []rune 转换作用于 UTF-8 编码的字符串时,返回该字符串的 Unicode 码点序列:
s := “ABC”
r := []rune(s)
4个标准包对字符串操作特别重要: bytes, strings, strconv 和 unicode。
strings 包提供了许多函数,用于搜索、替换、比较、修整、切分与连接字符串。
bytes 包也有类似的函数,用于操作字节 slice([]byte 类型)。
由于字符串不可变,因此按增量方式构建字符串会导致多次内存分配和复制。使用 bytes.Buffer 类型会更高效。
strconv 用于转换布尔值、整数、浮点数为与之对应的字符串形式,或反之。
unicode 包有判别文字符号值特征的函数,如 IsDigit、IsLetter、IsUpper 和 IsLower。
字节 slice 的元素允许随意修改。
要将整数转换成字符串,一种选择是使用 fmt.Sprintf, 另一种做法是用函数 strconv.Itoa(“Integer to ASCII”)
x := 123
y := fmt.Sprintf("%d", x)
fmt.Println(y, strconv.Itoa(x))
FormatInt 和 FormatUint 可以按不同进位二进制格式化数字。
strconv.FormatInt(123, 2) // 二进制。
strconv.Atoi(“123”) // 把字符串转为 int
y, err := strconv.ParseInt(“123”, 10, 64) // 10进制,最长为64位。
若同时声明一组常量,除了第一项之外,其他项在等号右侧的表达式都可以省略,这意味着会复用前面一项的表达式及其类型。
const (
a = 1
b
c = 2
d
)
fmt.Println(a, b, c, d) // “1 1 2 2”
iota 初始值 0,逐项加 1。
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
const (
_ = 1 << (10 * iota)
KiB // 1024
MiB // 1048576
GiB // 1073741824
TiB // 1099511627776 (exceeds 1 << 32)
PiB // 1125899906842624
EiB // 1152921504606846976
ZiB // 1180591620717411303424 (exceeds 1 << 64)
YiB // 1208925819614629174706176
)
编译器将这些从属类型待定的常量表示为某些值,这些值比基本类型的数字精度更高,且算术精度高于原生的机器精度。于类型确定的常量相比,它们能写进更多表达式而不需转换类型
如 fmt.Println(YiB/ZiB)
只有常量才可以是无类型的。
go 语言中,只有大小不明确的 int 类型,不存在大小不确定的 float 类型和 complex 类型。
如果我们将无类型常量赋值给变量,需要显示转换,或者声明变量时声明想要的类型。
var i = int8(0)
var i int8 = 0
以下语句是可以编译的。
v := 1
但是以下语句不能编译。
v = 1
fmt.Printf("%T\n", 0) // int
fmt.Printf("%T\n", 0.0) // float64
fmt.Printf("%T\n", 0i) // complex128
fmt.Printf("%T\n", '\000') //int32(rune)