1.2.3 运算符与表达式

1.2.3 运算符与表达式 #

运算符是编程语言的基本构建块,用于对数据进行各种操作。Go 语言提供了丰富的运算符,包括算术运算符、比较运算符、逻辑运算符、位运算符等。本节将详细介绍这些运算符的使用方法和注意事项。

算术运算符 #

1. 基本算术运算 #

package main

import "fmt"

func main() {
    a, b := 15, 4

    // 基本算术运算符
    fmt.Printf("a = %d, b = %d\n", a, b)
    fmt.Printf("加法: %d + %d = %d\n", a, b, a+b)
    fmt.Printf("减法: %d - %d = %d\n", a, b, a-b)
    fmt.Printf("乘法: %d * %d = %d\n", a, b, a*b)
    fmt.Printf("除法: %d / %d = %d\n", a, b, a/b)
    fmt.Printf("取模: %d %% %d = %d\n", a, b, a%b)

    // 浮点数运算
    x, y := 15.0, 4.0
    fmt.Printf("\n浮点数运算:\n")
    fmt.Printf("x = %.1f, y = %.1f\n", x, y)
    fmt.Printf("除法: %.1f / %.1f = %.3f\n", x, y, x/y)

    // 混合类型运算需要类型转换
    var intVal int = 10
    var floatVal float64 = 3.5
    result := float64(intVal) + floatVal
    fmt.Printf("混合运算: %d + %.1f = %.1f\n", intVal, floatVal, result)
}

2. 自增自减运算符 #

package main

import "fmt"

func main() {
    // 自增自减运算符
    i := 5
    fmt.Printf("初始值: i = %d\n", i)

    // 后置自增(Go 只支持后置)
    i++
    fmt.Printf("i++ 后: i = %d\n", i)

    // 后置自减
    i--
    fmt.Printf("i-- 后: i = %d\n", i)

    // 注意:Go 不支持前置自增自减
    // ++i  // 错误
    // --i  // 错误

    // 自增自减是语句,不是表达式
    j := 10
    // k := j++  // 错误:不能作为表达式使用

    // 正确的做法
    k := j
    j++
    fmt.Printf("j = %d, k = %d\n", j, k)

    // 在循环中的使用
    fmt.Print("循环输出: ")
    for n := 0; n < 5; n++ {
        fmt.Printf("%d ", n)
    }
    fmt.Println()
}

3. 复合赋值运算符 #

package main

import "fmt"

func main() {
    // 复合赋值运算符
    a := 10
    fmt.Printf("初始值: a = %d\n", a)

    a += 5  // 等价于 a = a + 5
    fmt.Printf("a += 5: a = %d\n", a)

    a -= 3  // 等价于 a = a - 3
    fmt.Printf("a -= 3: a = %d\n", a)

    a *= 2  // 等价于 a = a * 2
    fmt.Printf("a *= 2: a = %d\n", a)

    a /= 4  // 等价于 a = a / 4
    fmt.Printf("a /= 4: a = %d\n", a)

    a %= 3  // 等价于 a = a % 3
    fmt.Printf("a %%= 3: a = %d\n", a)

    // 位运算复合赋值
    b := 12  // 二进制: 1100
    fmt.Printf("\n位运算复合赋值:\n")
    fmt.Printf("初始值: b = %d (二进制: %04b)\n", b, b)

    b &= 10  // 按位与,二进制: 1010
    fmt.Printf("b &= 10: b = %d (二进制: %04b)\n", b, b)

    b |= 5   // 按位或,二进制: 0101
    fmt.Printf("b |= 5: b = %d (二进制: %04b)\n", b, b)

    b ^= 3   // 按位异或,二进制: 0011
    fmt.Printf("b ^= 3: b = %d (二进制: %04b)\n", b, b)

    b <<= 1  // 左移
    fmt.Printf("b <<= 1: b = %d (二进制: %04b)\n", b, b)

    b >>= 2  // 右移
    fmt.Printf("b >>= 2: b = %d (二进制: %04b)\n", b, b)
}

比较运算符 #

package main

import "fmt"

func main() {
    // 数值比较
    a, b := 10, 20
    fmt.Printf("a = %d, b = %d\n", a, b)
    fmt.Printf("a == b: %t\n", a == b)  // 等于
    fmt.Printf("a != b: %t\n", a != b)  // 不等于
    fmt.Printf("a < b: %t\n", a < b)    // 小于
    fmt.Printf("a <= b: %t\n", a <= b)  // 小于等于
    fmt.Printf("a > b: %t\n", a > b)    // 大于
    fmt.Printf("a >= b: %t\n", a >= b)  // 大于等于

    // 字符串比较(按字典序)
    str1, str2 := "apple", "banana"
    fmt.Printf("\n字符串比较:\n")
    fmt.Printf("str1 = %s, str2 = %s\n", str1, str2)
    fmt.Printf("str1 == str2: %t\n", str1 == str2)
    fmt.Printf("str1 < str2: %t\n", str1 < str2)
    fmt.Printf("str1 > str2: %t\n", str1 > str2)

    // 布尔值比较
    bool1, bool2 := true, false
    fmt.Printf("\n布尔值比较:\n")
    fmt.Printf("bool1 = %t, bool2 = %t\n", bool1, bool2)
    fmt.Printf("bool1 == bool2: %t\n", bool1 == bool2)
    fmt.Printf("bool1 != bool2: %t\n", bool1 != bool2)

    // 指针比较
    x, y := 42, 42
    px, py := &x, &y
    pz := &x
    fmt.Printf("\n指针比较:\n")
    fmt.Printf("px == py: %t (不同变量的地址)\n", px == py)
    fmt.Printf("px == pz: %t (同一变量的地址)\n", px == pz)
    fmt.Printf("*px == *py: %t (指向的值)\n", *px == *py)
}

逻辑运算符 #

package main

import "fmt"

func main() {
    // 逻辑运算符
    a, b := true, false
    fmt.Printf("a = %t, b = %t\n", a, b)

    // 逻辑与 (&&)
    fmt.Printf("a && b: %t\n", a && b)
    fmt.Printf("a && true: %t\n", a && true)
    fmt.Printf("false && b: %t\n", false && b)

    // 逻辑或 (||)
    fmt.Printf("a || b: %t\n", a || b)
    fmt.Printf("a || false: %t\n", a || false)
    fmt.Printf("false || false: %t\n", false || false)

    // 逻辑非 (!)
    fmt.Printf("!a: %t\n", !a)
    fmt.Printf("!b: %t\n", !b)
    fmt.Printf("!!a: %t\n", !!a)

    // 短路求值演示
    fmt.Printf("\n短路求值演示:\n")

    // 逻辑与的短路求值
    if false && expensiveOperation() {
        fmt.Println("这行不会执行")
    }

    // 逻辑或的短路求值
    if true || expensiveOperation() {
        fmt.Println("这行会执行,但 expensiveOperation 不会被调用")
    }

    // 复杂逻辑表达式
    x, y, z := 5, 10, 15
    fmt.Printf("\n复杂逻辑表达式:\n")
    fmt.Printf("x = %d, y = %d, z = %d\n", x, y, z)

    result1 := (x < y) && (y < z)
    fmt.Printf("(x < y) && (y < z): %t\n", result1)

    result2 := (x > y) || (y < z)
    fmt.Printf("(x > y) || (y < z): %t\n", result2)

    result3 := !(x == y) && (z > y)
    fmt.Printf("!(x == y) && (z > y): %t\n", result3)
}

func expensiveOperation() bool {
    fmt.Println("执行了昂贵的操作")
    return true
}

位运算符 #

package main

import "fmt"

func main() {
    // 位运算符演示
    a, b := 12, 10  // a = 1100, b = 1010 (二进制)
    fmt.Printf("a = %d (二进制: %04b)\n", a, a)
    fmt.Printf("b = %d (二进制: %04b)\n", b, b)

    // 按位与 (&)
    and := a & b
    fmt.Printf("a & b = %d (二进制: %04b)\n", and, and)

    // 按位或 (|)
    or := a | b
    fmt.Printf("a | b = %d (二进制: %04b)\n", or, or)

    // 按位异或 (^)
    xor := a ^ b
    fmt.Printf("a ^ b = %d (二进制: %04b)\n", xor, xor)

    // 按位取反 (^) - 一元运算符
    notA := ^a
    fmt.Printf("^a = %d (二进制: %032b)\n", notA, uint32(notA))

    // 左移 (<<)
    leftShift := a << 2
    fmt.Printf("a << 2 = %d (二进制: %08b)\n", leftShift, leftShift)

    // 右移 (>>)
    rightShift := a >> 1
    fmt.Printf("a >> 1 = %d (二进制: %04b)\n", rightShift, rightShift)

    // 位运算的实际应用
    fmt.Printf("\n位运算实际应用:\n")

    // 检查奇偶性
    numbers := []int{1, 2, 3, 4, 5, 6, 7, 8}
    for _, num := range numbers {
        if num&1 == 0 {
            fmt.Printf("%d 是偶数\n", num)
        } else {
            fmt.Printf("%d 是奇数\n", num)
        }
    }

    // 权限系统示例
    fmt.Printf("\n权限系统示例:\n")
    const (
        READ    = 1 << iota  // 1 (001)
        WRITE                // 2 (010)
        EXECUTE              // 4 (100)
    )

    // 设置权限
    var permission int = READ | WRITE  // 3 (011)
    fmt.Printf("初始权限: %d (二进制: %03b)\n", permission, permission)

    // 检查权限
    fmt.Printf("有读权限: %t\n", permission&READ != 0)
    fmt.Printf("有写权限: %t\n", permission&WRITE != 0)
    fmt.Printf("有执行权限: %t\n", permission&EXECUTE != 0)

    // 添加权限
    permission |= EXECUTE
    fmt.Printf("添加执行权限后: %d (二进制: %03b)\n", permission, permission)

    // 移除权限
    permission &^= WRITE  // 清除写权限
    fmt.Printf("移除写权限后: %d (二进制: %03b)\n", permission, permission)
}

运算符优先级 #

package main

import "fmt"

func main() {
    // 运算符优先级演示
    fmt.Println("运算符优先级演示:")

    // 算术运算符优先级
    result1 := 2 + 3 * 4
    result2 := (2 + 3) * 4
    fmt.Printf("2 + 3 * 4 = %d\n", result1)      // 14
    fmt.Printf("(2 + 3) * 4 = %d\n", result2)    // 20

    // 比较和逻辑运算符优先级
    a, b, c := 5, 10, 15
    result3 := a < b && b < c
    result4 := a < b || b > c && c > a
    fmt.Printf("a < b && b < c = %t\n", result3)
    fmt.Printf("a < b || b > c && c > a = %t\n", result4)

    // 位运算符优先级
    x := 6   // 110
    y := 3   // 011
    result5 := x & y | 1  // (x & y) | 1
    result6 := x & (y | 1)
    fmt.Printf("x & y | 1 = %d\n", result5)      // 3
    fmt.Printf("x & (y | 1) = %d\n", result6)    // 2

    // 复杂表达式
    result7 := 1 + 2 * 3 > 5 && 4 < 8 || false
    fmt.Printf("1 + 2 * 3 > 5 && 4 < 8 || false = %t\n", result7)

    // 使用括号明确优先级
    result8 := ((1 + 2) * 3 > 5) && (4 < 8) || false
    fmt.Printf("((1 + 2) * 3 > 5) && (4 < 8) || false = %t\n", result8)
}

类型转换在表达式中的应用 #

package main

import (
    "fmt"
    "math"
)

func main() {
    // 不同类型的运算需要类型转换
    var intVal int = 10
    var floatVal float64 = 3.5
    var int32Val int32 = 20

    // 错误:不能直接运算不同类型
    // result := intVal + floatVal  // 编译错误

    // 正确:显式类型转换
    result1 := float64(intVal) + floatVal
    result2 := intVal + int(floatVal)  // 注意:会截断小数部分
    result3 := int64(intVal) + int64(int32Val)

    fmt.Printf("float64(intVal) + floatVal = %.1f\n", result1)
    fmt.Printf("intVal + int(floatVal) = %d\n", result2)
    fmt.Printf("int64(intVal) + int64(int32Val) = %d\n", result3)

    // 类型提升在表达式中的应用
    var a int8 = 100
    var b int8 = 50

    // 小整数类型在运算时会提升为 int
    sum := a + b  // 结果是 int 类型
    fmt.Printf("类型: %T, 值: %d\n", sum, sum)

    // 溢出处理
    var maxInt8 int8 = 127
    var overflow int8 = maxInt8 + 1  // 溢出
    fmt.Printf("溢出结果: %d\n", overflow)

    // 安全的运算
    if int(maxInt8)+1 > 127 {
        fmt.Println("运算会导致 int8 溢出")
    }

    // 浮点数精度问题
    var f1 float32 = 1.0000001
    var f2 float32 = 1.0000002
    fmt.Printf("float32 精度: %.10f\n", f1-f2)

    var d1 float64 = 1.0000001
    var d2 float64 = 1.0000002
    fmt.Printf("float64 精度: %.10f\n", d1-d2)
}

表达式求值和副作用 #

package main

import "fmt"

func main() {
    // 表达式求值顺序
    fmt.Println("表达式求值顺序:")

    i := 0
    // 注意:Go 语言中函数参数的求值顺序是未定义的
    result := add(increment(&i), increment(&i))
    fmt.Printf("结果: %d, i的最终值: %d\n", result, i)

    // 安全的做法:避免在同一表达式中多次修改同一变量
    i = 0
    a := increment(&i)
    b := increment(&i)
    result = add(a, b)
    fmt.Printf("安全的结果: %d, i的最终值: %d\n", result, i)

    // 短路求值的副作用
    fmt.Println("\n短路求值的副作用:")

    counter := 0
    if false && incrementCounter(&counter) > 0 {
        fmt.Println("这行不会执行")
    }
    fmt.Printf("counter (&&): %d\n", counter)  // 0,因为短路求值

    counter = 0
    if true || incrementCounter(&counter) > 0 {
        fmt.Println("这行会执行")
    }
    fmt.Printf("counter (||): %d\n", counter)  // 0,因为短路求值

    // 复杂表达式的求值
    fmt.Println("\n复杂表达式求值:")

    x, y, z := 1, 2, 3
    result = complexExpression(x, y, z)
    fmt.Printf("复杂表达式结果: %d\n", result)
}

func add(a, b int) int {
    fmt.Printf("add(%d, %d)\n", a, b)
    return a + b
}

func increment(ptr *int) int {
    *ptr++
    fmt.Printf("increment: %d\n", *ptr)
    return *ptr
}

func incrementCounter(counter *int) int {
    *counter++
    fmt.Printf("incrementCounter: %d\n", *counter)
    return *counter
}

func complexExpression(x, y, z int) int {
    // 复杂表达式:包含多种运算符
    return (x+y)*z - x*y + (z<<1) | (x^y)
}

实际应用示例 #

1. 数学计算器 #

package main

import (
    "fmt"
    "math"
)

// 计算器结构
type Calculator struct {
    precision int
}

// 创建计算器
func NewCalculator(precision int) *Calculator {
    return &Calculator{precision: precision}
}

// 基本运算
func (c *Calculator) Add(a, b float64) float64 {
    return c.round(a + b)
}

func (c *Calculator) Subtract(a, b float64) float64 {
    return c.round(a - b)
}

func (c *Calculator) Multiply(a, b float64) float64 {
    return c.round(a * b)
}

func (c *Calculator) Divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为零")
    }
    return c.round(a / b), nil
}

func (c *Calculator) Power(base, exponent float64) float64 {
    return c.round(math.Pow(base, exponent))
}

func (c *Calculator) Sqrt(a float64) (float64, error) {
    if a < 0 {
        return 0, fmt.Errorf("负数没有实数平方根")
    }
    return c.round(math.Sqrt(a)), nil
}

// 四舍五入到指定精度
func (c *Calculator) round(value float64) float64 {
    multiplier := math.Pow(10, float64(c.precision))
    return math.Round(value*multiplier) / multiplier
}

// 复合运算
func (c *Calculator) QuadraticFormula(a, b, c_coeff float64) (float64, float64, error) {
    discriminant := b*b - 4*a*c_coeff
    if discriminant < 0 {
        return 0, 0, fmt.Errorf("判别式小于零,无实数解")
    }

    sqrtDiscriminant := math.Sqrt(discriminant)
    x1 := (-b + sqrtDiscriminant) / (2 * a)
    x2 := (-b - sqrtDiscriminant) / (2 * a)

    return c.round(x1), c.round(x2), nil
}

func main() {
    calc := NewCalculator(3)

    // 基本运算测试
    fmt.Println("基本运算测试:")
    fmt.Printf("10 + 3.5 = %.3f\n", calc.Add(10, 3.5))
    fmt.Printf("10 - 3.5 = %.3f\n", calc.Subtract(10, 3.5))
    fmt.Printf("10 * 3.5 = %.3f\n", calc.Multiply(10, 3.5))

    if result, err := calc.Divide(10, 3.5); err != nil {
        fmt.Printf("除法错误: %v\n", err)
    } else {
        fmt.Printf("10 / 3.5 = %.3f\n", result)
    }

    fmt.Printf("2^10 = %.3f\n", calc.Power(2, 10))

    if result, err := calc.Sqrt(16); err != nil {
        fmt.Printf("平方根错误: %v\n", err)
    } else {
        fmt.Printf("√16 = %.3f\n", result)
    }

    // 二次方程求解
    fmt.Println("\n二次方程求解 (x² - 5x + 6 = 0):")
    if x1, x2, err := calc.QuadraticFormula(1, -5, 6); err != nil {
        fmt.Printf("求解错误: %v\n", err)
    } else {
        fmt.Printf("解: x1 = %.3f, x2 = %.3f\n", x1, x2)
    }
}

2. 位操作工具 #

package main

import "fmt"

// 位操作工具
type BitUtils struct{}

// 检查第n位是否为1
func (bu BitUtils) IsBitSet(value uint32, position uint) bool {
    return (value & (1 << position)) != 0
}

// 设置第n位为1
func (bu BitUtils) SetBit(value uint32, position uint) uint32 {
    return value | (1 << position)
}

// 清除第n位(设为0)
func (bu BitUtils) ClearBit(value uint32, position uint) uint32 {
    return value &^ (1 << position)
}

// 切换第n位
func (bu BitUtils) ToggleBit(value uint32, position uint) uint32 {
    return value ^ (1 << position)
}

// 计算设置的位数
func (bu BitUtils) CountSetBits(value uint32) int {
    count := 0
    for value != 0 {
        count += int(value & 1)
        value >>= 1
    }
    return count
}

// 获取最低位的1
func (bu BitUtils) GetLowestSetBit(value uint32) uint32 {
    return value & (-value)
}

// 检查是否为2的幂
func (bu BitUtils) IsPowerOfTwo(value uint32) bool {
    return value != 0 && (value&(value-1)) == 0
}

// 下一个2的幂
func (bu BitUtils) NextPowerOfTwo(value uint32) uint32 {
    if value == 0 {
        return 1
    }
    value--
    value |= value >> 1
    value |= value >> 2
    value |= value >> 4
    value |= value >> 8
    value |= value >> 16
    return value + 1
}

// 权限管理系统
type Permission uint32

const (
    PermissionRead Permission = 1 << iota
    PermissionWrite
    PermissionExecute
    PermissionDelete
    PermissionAdmin
)

func (p Permission) String() string {
    var permissions []string
    if p&PermissionRead != 0 {
        permissions = append(permissions, "READ")
    }
    if p&PermissionWrite != 0 {
        permissions = append(permissions, "WRITE")
    }
    if p&PermissionExecute != 0 {
        permissions = append(permissions, "EXECUTE")
    }
    if p&PermissionDelete != 0 {
        permissions = append(permissions, "DELETE")
    }
    if p&PermissionAdmin != 0 {
        permissions = append(permissions, "ADMIN")
    }

    if len(permissions) == 0 {
        return "NONE"
    }

    result := permissions[0]
    for i := 1; i < len(permissions); i++ {
        result += " | " + permissions[i]
    }
    return result
}

func main() {
    bu := BitUtils{}

    // 位操作演示
    fmt.Println("位操作演示:")
    var value uint32 = 12  // 1100
    fmt.Printf("初始值: %d (二进制: %04b)\n", value, value)

    // 检查位
    for i := uint(0); i < 4; i++ {
        fmt.Printf("第%d位: %t\n", i, bu.IsBitSet(value, i))
    }

    // 设置位
    value = bu.SetBit(value, 0)
    fmt.Printf("设置第0位后: %d (二进制: %04b)\n", value, value)

    // 清除位
    value = bu.ClearBit(value, 2)
    fmt.Printf("清除第2位后: %d (二进制: %04b)\n", value, value)

    // 切换位
    value = bu.ToggleBit(value, 1)
    fmt.Printf("切换第1位后: %d (二进制: %04b)\n", value, value)

    // 计算设置的位数
    fmt.Printf("设置的位数: %d\n", bu.CountSetBits(value))

    // 2的幂检查
    testValues := []uint32{1, 2, 3, 4, 8, 15, 16, 32}
    fmt.Println("\n2的幂检查:")
    for _, val := range testValues {
        fmt.Printf("%d 是2的幂: %t\n", val, bu.IsPowerOfTwo(val))
    }

    // 权限管理演示
    fmt.Println("\n权限管理演示:")

    // 创建用户权限
    var userPerm Permission = PermissionRead | PermissionWrite
    fmt.Printf("用户权限: %s\n", userPerm)

    // 检查权限
    fmt.Printf("有读权限: %t\n", userPerm&PermissionRead != 0)
    fmt.Printf("有删除权限: %t\n", userPerm&PermissionDelete != 0)

    // 添加权限
    userPerm |= PermissionExecute
    fmt.Printf("添加执行权限后: %s\n", userPerm)

    // 移除权限
    userPerm &^= PermissionWrite
    fmt.Printf("移除写权限后: %s\n", userPerm)

    // 管理员权限
    adminPerm := PermissionRead | PermissionWrite | PermissionExecute | PermissionDelete | PermissionAdmin
    fmt.Printf("管理员权限: %s\n", adminPerm)
}

常见错误和注意事项 #

1. 整数溢出 #

package main

import (
    "fmt"
    "math"
)

func main() {
    // 整数溢出问题
    var maxInt8 int8 = 127
    fmt.Printf("int8 最大值: %d\n", maxInt8)

    // 溢出导致回绕
    maxInt8++
    fmt.Printf("溢出后: %d\n", maxInt8)  // -128

    // 安全的溢出检查
    func safeAdd(a, b int8) (int8, error) {
        if a > 0 && b > 0 && a > math.MaxInt8-b {
            return 0, fmt.Errorf("正溢出")
        }
        if a < 0 && b < 0 && a < math.MinInt8-b {
            return 0, fmt.Errorf("负溢出")
        }
        return a + b, nil
    }

    if result, err := safeAdd(100, 50); err != nil {
        fmt.Printf("加法溢出: %v\n", err)
    } else {
        fmt.Printf("安全加法结果: %d\n", result)
    }
}

2. 浮点数比较 #

package main

import (
    "fmt"
    "math"
)

func main() {
    // 浮点数精度问题
    a := 0.1 + 0.2
    b := 0.3

    fmt.Printf("0.1 + 0.2 = %.17f\n", a)
    fmt.Printf("0.3 = %.17f\n", b)
    fmt.Printf("相等吗? %t\n", a == b)  // false!

    // 正确的浮点数比较
    const epsilon = 1e-9

    func floatEqual(x, y, epsilon float64) bool {
        return math.Abs(x-y) < epsilon
    }

    fmt.Printf("近似相等吗? %t\n", floatEqual(a, b, epsilon))

    // 相对误差比较
    func floatEqualRel(x, y, relativeEpsilon float64) bool {
        if x == y {
            return true
        }

        diff := math.Abs(x - y)
        largest := math.Max(math.Abs(x), math.Abs(y))

        return diff <= relativeEpsilon*largest
    }

    fmt.Printf("相对误差比较: %t\n", floatEqualRel(a, b, 1e-9))
}

3. 运算符优先级陷阱 #

package main

import "fmt"

func main() {
    // 位运算符优先级陷阱
    x := 6
    y := 3

    // 错误的理解
    result1 := x & y == 0  // 实际上是 x & (y == 0)
    fmt.Printf("x & y == 0: %t (错误的理解)\n", result1)

    // 正确的写法
    result2 := (x & y) == 0
    fmt.Printf("(x & y) == 0: %t (正确的写法)\n", result2)

    // 逻辑运算符优先级
    a, b, c := true, false, true

    // 可能引起混淆的表达式
    result3 := a || b && c  // 实际上是 a || (b && c)
    result4 := (a || b) && c

    fmt.Printf("a || b && c: %t\n", result3)
    fmt.Printf("(a || b) && c: %t\n", result4)

    // 建议:使用括号明确优先级
    fmt.Println("建议使用括号明确表达意图")
}

小结 #

本节详细介绍了 Go 语言的运算符和表达式,主要内容包括:

运算符类型 #

  • 算术运算符:+, -, _, /, %, ++, –, +=, -=, _=, /=, %=
  • 比较运算符:==, !=, <, <=, >, >=
  • 逻辑运算符:&&, ||, !
  • 位运算符:&, |, ^, «, », &^

重要概念 #

  • 运算符优先级:理解不同运算符的优先级顺序
  • 短路求值:逻辑运算符的短路特性
  • 类型转换:不同类型间的运算需要显式转换
  • 溢出处理:注意整数运算的溢出问题

最佳实践 #

  • 使用括号明确表达式的优先级
  • 注意浮点数比较的精度问题
  • 避免在表达式中产生副作用
  • 合理使用位运算符进行高效操作

掌握运算符和表达式的使用是编程的基础技能,为后续学习控制结构和函数奠定了重要基础。


练习题:

  1. 编写程序演示各种运算符的优先级
  2. 实现一个安全的整数运算库,包含溢出检查
  3. 创建一个位操作工具类,实现常用的位操作功能
  4. 编写一个表达式求值器,支持基本的数学运算
  5. 实现一个权限管理系统,使用位运算管理用户权限