Go语言数据类型与运算符详解
数据类型
动态类型与静态类型编程语言
动态类型编程语言在运行时判断数据类型,而静态类型编程语言(如Go、C)需要在开发时定义变量并分配空间大小。在Go语言中,每种基本数据类型都有默认的空间大小。
1、布尔型数据
布尔型的值只能是常量true或false。例如:var flag bool = true。
package main
import "fmt"
func main() {
// 声明布尔变量
var isValid bool = true
var isNotFound bool = false
// 输出布尔值及其类型
fmt.Println(isValid, isNotFound)
fmt.Printf("%T,%t\n", isValid, isValid)
fmt.Printf("%T,%t\n", isNotFound, isNotFound)
// 数值比较结果为布尔值
var x int = 10
var y int = 20
fmt.Println(x < y)
// 条件判断
if x < y {
fmt.Println("x小于y")
} else {
fmt.Println("x大于或等于y")
}
// 布尔类型默认值为false
var defaultBool bool
fmt.Println("布尔类型默认值:", defaultBool)
}
2、整型数据
Go语言支持整型和浮点型数字,包括基于架构的类型如uint(无符号)和int(有符号)。每种数字类型都有其特定的取值范围。
| 类型 | 描述 |
|---|---|
| uint8 | 无符号8位整型 (0 到 255) |
| uint16 | 无符号16位整型 (0 到 65535) |
| uint32 | 无符号32位整型 (0 到 4294967295) |
| uint64 | 无符号64位整型 (0 到 18446744073709551615) |
| int8 | 有符号8位整型 (-128 到 127) |
| int16 | 有符号16位整型 (-32768 到 32767) |
| int32 | 有符号32位整型 (-2147483648 到 2147483647) |
| int64 | 有符号64位整型 (-9223372036854775808 到 9223372036854775807) |
有符号数和无符号数的区别在于0为分界点,正负方向扩展。空间大小由位数决定,这是数据类型值的上限。
3、浮点数
package main
import "fmt"
func main() {
// 默认为float64类型
var num1 float64
var num2 float32
num1 = 3.14159
num2 = 5.7
fmt.Printf("num1=%f,num1=%T\n", num1, num1)
fmt.Printf("num2=%f,num2=%T\n", num2, num2)
// 控制小数位数
fmt.Printf("num1保留三位小数=%.3f,num1=%T\n", num1, num1)
fmt.Printf("num1保留两位小数=%.2f,num1=%T\n", num1, num1)
}
package main
import "fmt"
func main() {
// 浮点数由符号位+指数位+尾数位组成,可能导致精度损失
var val1 float32
var val2 float64
val1 = -123.0000901
val2 = -123.0000901
fmt.Println(val1)
fmt.Println(val2)
// float32和float64的精度表现不同
}
4、特殊数字类型
package main
import "fmt"
func main() {
// byte类型类似于uint8,用于表示0-255之间的整数
var byteVal byte = 255
fmt.Println(byteVal) // 255
fmt.Printf("%T\n", byteVal) // uint8
// rune类型等同于int32,用于表示Unicode字符
var runeVal rune = '中'
fmt.Println(runeVal)
fmt.Printf("%T\n", runeVal)
// int类型根据系统架构确定大小
var systemInt int = 100000000000000
fmt.Println(systemInt)
fmt.Printf("%T\n", systemInt)
}
byte和rune类型主要用于与int类型区分,分别用于表示字节和字符。
5、字符串类型
字符串是由固定长度的字符连接而成的字符序列,可以包含中文或英文等。Go语言中所有字符串都是由单个字符连接而成,兼容全世界文字。
常见的编码包括UTF-8(兼容绝大多数文字和符号)、GBK(中文编码表)和Unicode(全球文字编码表)。
package main
import "fmt"
func main() {
var text string
text = "世界"
fmt.Printf("%T,%s\n", text, text) //string,世界
// 单引号表示字符,双引号表示字符串
str1 := "b"
char1 := 'B'
char2 := '魅'
fmt.Printf("%T,%s\n", str1, str1)
fmt.Printf("%T,%d\n", char1, char1)
fmt.Printf("%T,%d\n", char2, char2)
}
6、数据类型转换
在必要且可行的情况下,一种类型的值可以转换为另一种类型的值。Go语言不支持隐式类型转换,所有类型转换都必须显式声明:新类型值 = 新类型(旧类型值)。
package main
import "fmt"
func main() {
// 浮点数转整数直接截断,不是四舍五入
// 语法:新类型的值 = 新类型(旧类型的值)
decimal := 8.9
integer := int(decimal)
fmt.Printf("%T,%d\n", integer, integer)
whole := 42
floating := float64(whole)
fmt.Printf("%T,%f\n", floating, floating)
// 布尔类型不支持转换为其他类型
// var status bool = true
// number := int(status) // 错误操作
}
运算符
1、算术运算符
package main
import "fmt"
func main() {
// 算术运算符:+ - * / % ++ --
var firstNum int = 10
var secondNum int = 3
var result int // 存储运算结果
// 二元运算符需要两个操作数
result = firstNum + secondNum
fmt.Println(result)
result = firstNum - secondNum
fmt.Println(result)
result = firstNum * secondNum
fmt.Println(result)
result = firstNum / secondNum // 整数除法,结果为3
fmt.Println(result)
result = firstNum % secondNum // 取余运算,结果为1
fmt.Println(result)
// 一元运算符只需一个操作数
fmt.Println(firstNum)
firstNum++ // 自增操作,相当于 firstNum = firstNum + 1
fmt.Println(firstNum)
firstNum = 10
firstNum-- // 自减操作,相当于 firstNum = firstNum - 1
fmt.Println(firstNum)
}
2、关系运算符
关系运算符用于比较两个值,结果为布尔值(true或false)。
- 大于 >
- 小于 <
- 等于 ==
- 不等于 !=
- 大于等于 >=
- 小于等于 <=
package main
import "fmt"
func main() {
var valueA int = 25
var valueB int = 15
fmt.Println(valueA > valueB)
fmt.Println(valueA < valueB)
fmt.Println(valueA == valueB)
fmt.Println(valueA != valueB)
fmt.Println(valueA >= valueB)
fmt.Println(valueA <= valueB)
}
3、逻辑运算符
逻辑运算符用于组合多个条件判断:
- && 与(AND):所有条件都为真时结果才为真
- || 或(OR):任一条件为真时结果就为真
- ! 非(NOT):取反操作,真变假,假变真
package main
import "fmt"
func main() {
var condition1 bool = true
var condition2 bool = false
var condition3 bool = false
var condition4 bool = false
var condition5 bool = true
fmt.Println(condition1 && condition2)
fmt.Println(condition3 && condition4)
fmt.Println(condition1 && condition5)
fmt.Println(1 != 1 && condition5 || condition4)
fmt.Println(1 == 1 && condition5 || condition4)
}
4、位运算符
位运算符直接对整数的二进制位进行操作,常用于加密解密和高效计算。
| 运算符 | 描述 | 示例 |
|---|---|---|
| & | 按位与:两个位都为1时结果为1 | (A & B) 结果为 12 |
| | | 按位或:两个位都为0时结果为0 | (A | B) 结果为 61 |
| ^ | 按位异或:位相同时为0,不同时为1 | (A ^ B) 结果为 49 |
| &^ | 位清空:目标位为1时结果位为0 | (A &^ B) 结果为 48 |
| << | 左移:左移n位相当于乘以2的n次方 | A << 2 结果为 240 |
| >> | 右移:右移n位相当于除以2的n次方 | A >> 2 结果为 15 |
package main
import "fmt"
func main() {
// 位运算操作二进制位
var numA int = 60 // 二进制: 0011 1100
var numB int = 13 // 二进制: 0000 1101
// 按位与
fmt.Println(numA & numB)
// 0011 1100
// 0000 1101
// 0000 1100 (12)
// 按位或
fmt.Println(numA | numB)
// 0011 1100
// 0000 1101
// 0011 1101 (61)
// 按位异或
fmt.Println(numA ^ numB)
// 0011 1100
// 0000 1101
// 0011 0001 (49)
// 位清空
fmt.Println(numA &^ numB)
// 0011 1100
// 0000 1101
// 0011 0000 (48)
// 左移
fmt.Println(numA << 2) // 240 (1111 0000)
// 右移
fmt.Println(numA >> 2) // 15 (0000 1111)
}
5、赋值运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
| = | 简单赋值 | C = A + B |
| += | 相加后赋值 | C += A 等于 C = C + A |
| -= | 相减后赋值 | C -= A 等于 C = C - A |
| *= | 相乘后赋值 | C *= A 等于 C = C * A |
| /= | 相除后赋值 | C /= A 等于 C = C / A |
| %= | 取余后赋值 | C %= A 等于 C = C % A |
| <<= | 左移后赋值 | C <<= 2 等于 C = C << 2 |
| >= | 右移后赋值 | C >>= 2 等于 C = C >> 2 |
| &= | 按位与后赋值 | C &= 2 等于 C = C & 2 |
| ^= | 按位异或后赋值 | C ^= 2 等于 C = C ^ 2 |
| |= | 按位或后赋值 | C |= 2 等于 C = C | 2 |
6、其他运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
| & | 返回变量存储地址 | &a; 给出变量a的实际地址 |
| * | 指针变量 | *a; 是一个指针变量 |