目录

Go 运算符

运算符是编程语言中用于执行操作的基本符号。Go 提供了丰富的运算符,包括算术、关系、逻辑、位运算和赋值运算符。本篇将逐一介绍各类运算符的用法,并配以代码示例。

算术运算符

Go 支持以下算术运算符:

运算符 说明 示例
+ 加法 a + b
- 减法 a - b
* 乘法 a * b
/ 除法 a / b
% 取余 a % b
++ 自增 a++
-- 自减 a--

基本运算

package main

import "fmt"

func main() {
    a, b := 17, 5

    fmt.Println("a + b =", a+b) // 22
    fmt.Println("a - b =", a-b) // 12
    fmt.Println("a * b =", a*b) // 85
    fmt.Println("a / b =", a/b) // 3(整数除法,截断小数部分)
    fmt.Println("a %% b =", a%b) // 2(取余)
}

整数除法与浮点除法

package main

import "fmt"

func main() {
    // 整数除法会截断
    fmt.Println("10 / 3 =", 10/3)     // 3
    fmt.Println("10 %% 3 =", 10%3)     // 1

    // 浮点除法保留小数
    fmt.Println("10.0 / 3.0 =", 10.0/3.0) // 3.3333333333333335
}

自增与自减

Go 中的 ++--语句而非表达式,只能作为独立语句使用,不能放在表达式中:

package main

import "fmt"

func main() {
    x := 10
    x++ // 等价于 x = x + 1
    fmt.Println("x++ 后:", x) // 11

    x-- // 等价于 x = x - 1
    fmt.Println("x-- 后:", x) // 10

    // 以下写法在 Go 中是非法的:
    // y := x++  // 编译错误
    // fmt.Println(x++)  // 编译错误
}

关系运算符

关系运算符用于比较两个值,结果为布尔类型(truefalse)。

运算符 说明 示例
== 等于 a == b
!= 不等于 a != b
< 小于 a < b
> 大于 a > b
<= 小于等于 a <= b
>= 大于等于 a >= b
package main

import "fmt"

func main() {
    a, b := 10, 20

    fmt.Println("a == b:", a == b) // false
    fmt.Println("a != b:", a != b) // true
    fmt.Println("a < b:", a < b)   // true
    fmt.Println("a > b:", a > b)   // false
    fmt.Println("a <= b:", a <= b) // true
    fmt.Println("a >= b:", a >= b) // false

    // 字符串也可以比较(按字典序)
    s1, s2 := "apple", "banana"
    fmt.Println("s1 < s2:", s1 < s2) // true
    fmt.Println("s1 == s2:", s1 == s2) // false
}

逻辑运算符

逻辑运算符用于组合布尔表达式:

运算符 说明 示例
&& 逻辑与(短路求值) a && b
|| 逻辑或(短路求值) a || b
! 逻辑非 !a

短路求值

&&|| 具有短路特性:如果第一个操作数已经能确定结果,就不会计算第二个操作数。

package main

import "fmt"

func main() {
    a, b := true, false

    fmt.Println("a && b:", a && b) // false
    fmt.Println("a || b:", a || b) // true
    fmt.Println("!a:", !a)         // false

    // 短路求值的实际应用
    age := 20
    hasID := true

    // 如果 hasID 为 false,不会检查 age
    if hasID && age >= 18 {
        fmt.Println("允许进入")
    }

    // 空指针保护
    var name *string
    if name != nil && *name != "" {
        fmt.Println("名字:", *name)
    } else {
        fmt.Println("名字为空")
    }
}

位运算符

位运算符直接操作整数的二进制位:

运算符 说明 示例
& 按位与 a & b
| 按位或 a | b
^ 按位异或 a ^ b
&^ 按位清除(AND NOT) a &^ b
<< 左移 a << n
>> 右移 a >> n

基本位运算

package main

import "fmt"

func main() {
    a := 12 // 二进制: 1100
    b := 10 // 二进制: 1010

    fmt.Printf("a & b  = %d (二进制: %04b)\n", a&b, a&b)     // 8, 1000
    fmt.Printf("a | b  = %d (二进制: %04b)\n", a|b, a|b)     // 14, 1110
    fmt.Printf("a ^ b  = %d (二进制: %04b)\n", a^b, a^b)     // 6, 0110
    fmt.Printf("a &^ b = %d (二进制: %04b)\n", a&^b, a&^b)   // 4, 0100
}

位移运算

package main

import "fmt"

func main() {
    x := 8 // 二进制: 1000

    fmt.Printf("x << 1 = %d (二进制: %04b)\n", x<<1, x<<1) // 16, 10000
    fmt.Printf("x << 2 = %d (二进制: %04b)\n", x<<2, x<<2) // 32, 100000
    fmt.Printf("x >> 1 = %d (二进制: %04b)\n", x>>1, x>>1) // 4, 0100
    fmt.Printf("x >> 2 = %d (二进制: %04b)\n", x>>2, x>>2) // 2, 0010
}

位运算的实际应用

package main

import "fmt"

func main() {
    // 判断奇偶
    n := 7
    if n&1 == 1 {
        fmt.Println(n, "是奇数")
    }

    // 用位运算实现权限标志
    const (
        Read    = 1 << iota // 1 (001)
        Write               // 2 (010)
        Execute             // 4 (100)
    )

    // 设置权限
    perm := Read | Write // 011
    fmt.Printf("当前权限: %03b\n", perm)

    // 检查是否有某个权限
    if perm&Read != 0 {
        fmt.Println("有读权限")
    }
    if perm&Execute == 0 {
        fmt.Println("没有执行权限")
    }

    // 添加权限
    perm |= Execute
    fmt.Printf("添加执行权限后: %03b\n", perm)

    // 移除权限
    perm &^= Write
    fmt.Printf("移除写权限后: %03b\n", perm)
}

赋值运算符

运算符 说明 等价写法
= 赋值 a = b
+= 加后赋值 a = a + b
-= 减后赋值 a = a - b
*= 乘后赋值 a = a * b
/= 除后赋值 a = a / b
%= 取余后赋值 a = a % b
&= 按位与后赋值 a = a & b
|= 按位或后赋值 a = a | b
^= 按位异或后赋值 a = a ^ b
<<= 左移后赋值 a = a << b
>>= 右移后赋值 a = a >> b
package main

import "fmt"

func main() {
    x := 100

    x += 10 // x = x + 10
    fmt.Println("+= 10:", x) // 110

    x -= 30 // x = x - 30
    fmt.Println("-= 30:", x) // 80

    x *= 2 // x = x * 2
    fmt.Println("*= 2:", x) // 160

    x /= 4 // x = x / 4
    fmt.Println("/= 4:", x) // 40

    x %= 7 // x = x % 7
    fmt.Println("%%= 7:", x) // 5
}

运算符优先级

从高到低排列:

优先级 运算符
5(最高) *, /, %, <<, >>, &, &^
4 +, -, |, ^
3 ==, !=, <, <=, >, >=
2 &&
1(最低) ||

优先级示例

package main

import "fmt"

func main() {
    // 乘除优先于加减
    a := 2 + 3*4       // 2 + 12 = 14
    fmt.Println("2+3*4 =", a)

    // 关系运算符优先于逻辑运算符
    b := 10 > 5 && 3 < 7  // (10>5) && (3<7) → true && true → true
    fmt.Println("10>5 && 3<7 =", b)

    // 使用括号提高可读性
    c := (2 + 3) * 4     // 5 * 4 = 20
    fmt.Println("(2+3)*4 =", c)
}

建议:当表达式涉及多个运算符时,尽量使用括号明确优先级,提高代码可读性。

总结

本篇介绍了 Go 语言中的各类运算符。算术运算符用于数学计算,关系运算符用于比较,逻辑运算符用于组合布尔条件(支持短路求值),位运算符直接操作二进制位(常用于权限控制和底层优化),赋值运算符提供了简洁的复合赋值方式。理解运算符的优先级有助于避免逻辑错误,但更推荐的做法是使用括号让表达式的意图更加清晰。