基本数据类型与运算符
数字类型
Go语言支持整型和浮点型数字,并且原生支持复数,其中位的运算采用补码的形式。
Go 也有基于架构的类型,例如:int、uint 和 uintptr。这些类型长度是根据运行程序所在的操作系统决定的,例如
int和uint在 32 位操作系统上,它们均使用 32 位(4 个字节),在 64 位操作系统上,它们均使用 64 位(8 个字节)。uintptr的长度被设定为足够存放一个指针即可。
Go语言中是没用float类型的 但是有float32,float64顾名思义 float32占4字节,float64占8字节,这种的与操作系统架构无关,其有固定的大小。

int型是计算最快的类型
float32其精确度精确到了小数点后7位, float64其精确到了小数点后15位。
尽可能地使用 float64,因为 math 包中所有有关数学运算的函数都会要求接收这个类型
可以通过增加前缀0来表示8进制数(如:077),增加前缀0x来表示16进制数(如:0xFF),以及使用e来表示连乘。(如:1e3=1000)
你可以使用 a := uint64(0) 来同时完成类型转换和赋值操作,这样 a 的类型就是 uint64。
Go 中不允许不同类型之间的混合使用,但是对于对于常量的限制非常少,允许常量与变量之间的混合使用。
格式化说明符
在格式化字符串里,%d 用于格式化整数(%x 和 %X 用于格式化 16 进制表示的数字),%g 用于格式化浮点型(%f 输出浮点数,%e 输出科学计数表示法),%0nd 用于规定输出长度为 n 的整数,其中开头的数字 0 是必须的。
%n.mg 用于表示数字 n 并精确到小数点后 m 位,除了使用 g 之外,还可以使用 e 或者 f,例如:使用格式化字符串 %5.2e 来输出 3.4 的结果为 3.40e+00。
数字值转换
当进行类似 a32bitInt = int32(a32Float) 的转换时,小数点后的数字将被丢弃。这种情况一般发生当从取值范围较大的类型转换为取值范围较小的类型时,或者你可以写一个专门用于处理类型转换的函数来确保没有发生精度的丢失
Go 拥有以下复数类型:
complex64 (32 位实数和虚数)
complex128 (64 位实数和虚数)复数使用 re+imI 来表示,其中 re 代表实数部分,im 代表虚数部分,I 代表根号负 1
示例:
var c1 complex64 = 5 + 10i
fmt.Printf("The value is: %v", c1)
// 输出: 5 + 10i如果 re 和 im 的类型均为 float32,那么类型为 complex64 的复数 c 可以通过以下方式来获得:
c = complex(re, im)函数 real(c) 和 imag(c) 可以分别获得相应的实数和虚数部分。
在使用格式化说明符时,可以使用 %v 来表示复数,但当你希望只表示其中的一个部分的时候需要使用 %f。
复数支持和其它数字类型一样的运算。当你使用等号 == 或者不等号 != 对复数进行比较运算时,注意对精确度的把握。cmath 包中包含了一些操作复数的公共方法。如果你对内存的要求不是特别高,最好使用 complex128 作为计算类型,因为相关函数都使用这个类型的参数。
位运算
位运算只能用于整数类型的变量,且需当它们拥有等长位模式时。
%b 是用于表示位的格式化标识符。
二元运算符
- 按位与
&:
对应位置上的值经过和运算结果,并将 T (true) 替换为1,将 F (false) 替换为0
1 & 1 -> 1
1 & 0 -> 0
0 & 1 -> 0
0 & 0 -> 0- 按位或
|:
对应位置上的值经过或运算结果,并将 T (true) 替换为1,将 F (false) 替换为0
1 | 1 -> 1
1 | 0 -> 1
0 | 1 -> 1
0 | 0 -> 0- 按位异或
^:
对应位置上的值根据以下规则组合:
1 ^ 1 -> 0
1 ^ 0 -> 1
0 ^ 1 -> 1
0 ^ 0 -> 0- 位清除
&^:将指定位置上的值设置为0。
package main
import "fmt"
func main() {
var x uint8 = 15
var y uint8 = 4
fmt.Printf("%08b\n", x &^ y); // 00001011
}一元运算符
- 按位补足
^:
该运算符与异或运算符一同使用,即m^x,对于无符号x使用 “全部位设置为 1” 的规则,对于有符号x时使用m=-1。例如:
^10 = -01 ^ 10 = -11- 位左移
<<:
- 用法:
bitP << n。 bitP的位向左移动n位,右侧空白部分使用 0 填充;如果n等于 2,则结果是 2 的相应倍数,即 2 的n次方。例如:
1 << 10 // 等于 1 KB
1 << 20 // 等于 1 MB
1 << 30 // 等于 1 GB- 位右移
>>:
- 用法:
bitP >> n。 bitP的位向右移动n位,左侧空白部分使用 0 填充;如果n等于 2,则结果是当前值除以 2 的 n 次方。
当希望把结果赋值给第一个操作数时,可以简写为 a <<= 2 或者 b ^= a & 0xffffffff。
位左移常见实现存储单位的用例
使用位左移与 iota 计数配合可优雅地实现存储单位的常量枚举:
type ByteSize float64
const (
_ = iota // 通过赋值给空白标识符来忽略值
KB ByteSize = 1<<(10*iota)
MB
GB
TB
PB
EB
ZB
YB
)在通讯中使用位左移表示标识的用例
type BitFlag int
const (
Active BitFlag = 1 << iota // 1 << 0 == 1
Send // 1 << 1 == 2
Receive // 1 << 2 == 4
)
flag := Active | Send // == 3运算符与优先级
有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低:
优先级 运算符
7 ^ !
6 * / % << >> & &^
5 + - | ^
4 == != < <= >= >
3 <-
2 &&
1 ||当然,你可以通过使用括号来临时提升某个表达式的整体运算优先级。
类型别名
当你在使用某个类型时,你可以给它起另一个名字,然后你就可以在你的代码中使用新的名字(用于简化名称或解决名称冲突)。
在 type TZ int 中,TZ 就是 int 类型的新名称(用于表示程序中的时区),然后就可以使用 TZ 来操作 int 类型的数据
package main
import "fmt"
type TZ int
func main() {
var a, b TZ = 3, 4
c := a + b
fmt.Printf("c has the value: %d", c) // 输出:c has the value: 7
}字符类型
严格来说,这并不是 Go 语言的一个类型,字符只是整数的特殊用例。byte 类型是 uint8 的别名,对于只占用 1 个字节的传统 ASCII 编码的字符来说,完全没有问题。例如:var ch byte = 'A';字符使用单引号括起来。
在 ASCII 码表中,'A' 的值是 65,而使用 16 进制表示则为 41,所以下面的写法是等效的:
var ch byte = 65 或 var ch byte = '\x41'(\x 总是紧跟着长度为 2 的 16 进制数)
另外一种可能的写法是 \ 后面紧跟着长度为 3 的 8 进制数,例如:\377。
不过 Go 同样支持 Unicode(UTF-8),因此字符同样称为 Unicode 代码点或者 runes,并在内存中使用 int 来表示。在文档中,一般使用格式 U+hhhh 来表示,其中 h 表示一个 16 进制数。其实 rune 也是 Go 当中的一个类型,并且是 int32 的别名。
在书写 Unicode 字符时,需要在 16 进制数之前加上前缀 \u 或者 \U。
因为 Unicode 至少占用 2 个字节,所以我们使用 int16 或者 int 类型来表示。如果需要使用到 4 字节,则会加上 \U 前缀;前缀 \u 则总是紧跟着长度为 4 的 16 进制数,前缀 \U 紧跟着长度为 8 的 16 进制数。
var ch int = '\u0041'
var ch2 int = '\u03B2'
var ch3 int = '\U00101234'
fmt.Printf("%d - %d - %d\n", ch, ch2, ch3) // integer
fmt.Printf("%c - %c - %c\n", ch, ch2, ch3) // character
fmt.Printf("%X - %X - %X\n", ch, ch2, ch3) // UTF-8 bytes
fmt.Printf("%U - %U - %U", ch, ch2, ch3) // UTF-8 code point输出:
65 - 946 - 1053236
A - β - r
41 - 3B2 - 101234
U+0041 - U+03B2 - U+101234格式化说明符 %c 用于表示字符;当和字符配合使用时,%v 或 %d 会输出用于表示该字符的整数;%U 输出格式为 U+hhhh 的字符串。
包 unicode 包含了一些针对测试字符的非常有用的函数(其中 ch 代表字符):
- 判断是否为字母:
unicode.IsLetter(ch) - 判断是否为数字:
unicode.IsDigit(ch) - 判断是否为空白符号:
unicode.IsSpace(ch)
这些函数返回单个布尔值。包 utf8 拥有更多与 rune 类型相关的函数。
字符串
Go 中的字符串里面的字符也可能根据需要占用 1 至 4 个字节,这与其它语言如 C++、Java 或者 Python 不同(Java 始终使用 2 个字节)。Go 这样做的好处是不仅减少了内存和硬盘空间占用,同时也不用像其它语言那样需要对使用 UTF-8 字符集的文本进行编码和解码。
字符串是一种值类型,且值不可变,即创建某个文本后你无法再次修改这个文本的内容;更深入地讲,字符串是字节的定长数组。
转义符:
\n:换行符\r:回车符\t:tab 键\u或\U:Unicode 字符\\:反斜杠自身










