MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Go操作符与分隔符全解析

2021-10-017.9k 阅读

Go语言操作符概述

在Go语言中,操作符是构建表达式和执行各种操作的关键元素。它们允许程序员对数据进行算术运算、逻辑判断、比较、位操作等。Go语言提供了丰富的操作符集合,涵盖了从基本的算术操作符到复杂的逻辑和位操作符。理解这些操作符的工作原理和优先级是编写高效、正确Go代码的基础。

算术操作符

基本算术操作符

Go语言支持常见的基本算术操作符,包括加法(+)、减法(-)、乘法(*)、除法(/)和取模(%)。这些操作符作用于数值类型,如整数和浮点数。

  1. 加法操作符(+:用于将两个数值相加。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a + b
    fmt.Printf("%d + %d = %d\n", a, b, result)
}

在上述代码中,ab 相加,结果存储在 result 中,并通过 fmt.Printf 输出。

  1. 减法操作符(-:用于从一个数值中减去另一个数值。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a - b
    fmt.Printf("%d - %d = %d\n", a, b, result)
}

这里,a 减去 b,结果为 2

  1. 乘法操作符(*:用于将两个数值相乘。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a * b
    fmt.Printf("%d * %d = %d\n", a, b, result)
}

ab 相乘得到 15

  1. 除法操作符(/:用于将一个数值除以另一个数值。当操作数为整数时,结果是整数部分,小数部分会被截断。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a / b
    fmt.Printf("%d / %d = %d\n", a, b, result)
}

这里 5 除以 3,结果为 1,小数部分被丢弃。如果操作数至少有一个是浮点数,则会得到精确的除法结果:

package main

import "fmt"

func main() {
    a := 5.0
    b := 3.0
    result := a / b
    fmt.Printf("%.2f / %.2f = %.2f\n", a, b, result)
}

此代码输出 1.67,保留了两位小数。

  1. 取模操作符(%:用于计算两个整数相除的余数。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a % b
    fmt.Printf("%d %% %d = %d\n", a, b, result)
}

这里 53 取模,结果为 2。注意,在 fmt.Printf 中,% 需要转义为 %% 才能正确输出。

自增和自减操作符

Go语言还提供了自增(++)和自减(--)操作符,它们只能作为后缀使用,不能作为前缀。这两个操作符主要用于对整数类型的变量进行加一或减一的操作。

  1. 自增操作符(++:例如:
package main

import "fmt"

func main() {
    a := 5
    a++
    fmt.Printf("a after increment: %d\n", a)
}

a 的值从 5 变为 6

  1. 自减操作符(--:例如:
package main

import "fmt"

func main() {
    a := 5
    a--
    fmt.Printf("a after decrement: %d\n", a)
}

a 的值从 5 变为 4

比较操作符

比较操作符用于比较两个值,并返回一个布尔值(truefalse),表示比较的结果。Go语言中的比较操作符有:等于(==)、不等于(!=)、大于(>)、小于(<)、大于等于(>=)和小于等于(<=)。这些操作符可用于数值类型、布尔类型、字符串类型等。

  1. 等于操作符(==:用于判断两个值是否相等。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 5
    result := a == b
    fmt.Printf("%d == %d is %t\n", a, b, result)
}

这里 ab 相等,所以结果为 true

  1. 不等于操作符(!=:用于判断两个值是否不相等。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a != b
    fmt.Printf("%d != %d is %t\n", a, b, result)
}

由于 a 不等于 b,结果为 true

  1. 大于操作符(>:用于判断左边的值是否大于右边的值。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a > b
    fmt.Printf("%d > %d is %t\n", a, b, result)
}

因为 5 大于 3,结果为 true

  1. 小于操作符(<:用于判断左边的值是否小于右边的值。例如:
package main

import "fmt"

func main() {
    a := 3
    b := 5
    result := a < b
    fmt.Printf("%d < %d is %t\n", a, b, result)
}

这里 3 小于 5,结果为 true

  1. 大于等于操作符(>=:用于判断左边的值是否大于或等于右边的值。例如:
package main

import "fmt"

func main() {
    a := 5
    b := 5
    result1 := a >= b
    b = 3
    result2 := a >= b
    fmt.Printf("%d >= %d is %t\n", a, 5, result1)
    fmt.Printf("%d >= %d is %t\n", a, 3, result2)
}

第一个比较 5 >= 5true,第二个比较 5 >= 3 也为 true

  1. 小于等于操作符(<=:用于判断左边的值是否小于或等于右边的值。例如:
package main

import "fmt"

func main() {
    a := 3
    b := 5
    result1 := a <= b
    b = 3
    result2 := a <= b
    fmt.Printf("%d <= %d is %t\n", a, 5, result1)
    fmt.Printf("%d <= %d is %t\n", a, 3, result2)
}

第一个比较 3 <= 5true,第二个比较 3 <= 3 同样为 true

逻辑操作符

逻辑操作符用于对布尔值进行逻辑运算,返回一个布尔值。Go语言中的逻辑操作符有逻辑与(&&)、逻辑或(||)和逻辑非(!)。

  1. 逻辑与操作符(&&:只有当两个操作数都为 true 时,结果才为 true;否则结果为 false。例如:
package main

import "fmt"

func main() {
    a := true
    b := false
    result1 := a && a
    result2 := a && b
    fmt.Printf("true && true is %t\n", result1)
    fmt.Printf("true && false is %t\n", result2)
}

这里 true && true 结果为 truetrue && false 结果为 false

  1. 逻辑或操作符(||:只要两个操作数中有一个为 true,结果就为 true;只有当两个操作数都为 false 时,结果才为 false。例如:
package main

import "fmt"

func main() {
    a := true
    b := false
    result1 := a || a
    result2 := a || b
    result3 := b || b
    fmt.Printf("true || true is %t\n", result1)
    fmt.Printf("true || false is %t\n", result2)
    fmt.Printf("false || false is %t\n", result3)
}

true || truetrue || false 结果都为 true,而 false || false 结果为 false

  1. 逻辑非操作符(!:用于对一个布尔值取反。如果操作数为 true,则结果为 false;如果操作数为 false,则结果为 true。例如:
package main

import "fmt"

func main() {
    a := true
    result1 :=!a
    b := false
    result2 :=!b
    fmt.Printf("!true is %t\n", result1)
    fmt.Printf("!false is %t\n", result2)
}

!true 结果为 false!false 结果为 true

位操作符

位操作符用于对整数类型的二进制表示进行操作。Go语言中的位操作符有按位与(&)、按位或(|)、按位异或(^)、按位取反(^)、左移(<<)和右移(>>)。

  1. 按位与操作符(&:对两个整数的二进制位进行与操作,只有当对应的二进制位都为 1 时,结果位才为 1,否则为 0。例如:
package main

import "fmt"

func main() {
    a := 5  // 二进制: 0101
    b := 3  // 二进制: 0011
    result := a & b
    fmt.Printf("%d & %d = %d (binary: %b)\n", a, b, result, result)
}

这里 50101)和 30011)按位与,结果为 10001)。

  1. 按位或操作符(|:对两个整数的二进制位进行或操作,只要对应的二进制位有一个为 1,结果位就为 1,否则为 0。例如:
package main

import "fmt"

func main() {
    a := 5  // 二进制: 0101
    b := 3  // 二进制: 0011
    result := a | b
    fmt.Printf("%d | %d = %d (binary: %b)\n", a, b, result, result)
}

50101)和 30011)按位或,结果为 70111)。

  1. 按位异或操作符(^:对两个整数的二进制位进行异或操作,当对应的二进制位不同时,结果位为 1,否则为 0。例如:
package main

import "fmt"

func main() {
    a := 5  // 二进制: 0101
    b := 3  // 二进制: 0011
    result := a ^ b
    fmt.Printf("%d ^ %d = %d (binary: %b)\n", a, b, result, result)
}

50101)和 30011)按位异或,结果为 60110)。

  1. 按位取反操作符(^:对一个整数的二进制位进行取反操作,0 变为 11 变为 0。注意,Go语言中没有专门的按位取反操作符,而是复用了按位异或操作符(^)。例如:
package main

import "fmt"

func main() {
    a := 5  // 二进制: 0101
    result := ^a
    fmt.Printf("^%d = %d (binary: %b)\n", a, result, result)
}

这里 ^5 的结果取决于机器的整数表示方式,在大多数系统中,5 的二进制补码取反会得到 -6

  1. 左移操作符(<<:将一个整数的二进制位向左移动指定的位数,右边空出的位用 0 填充。例如:
package main

import "fmt"

func main() {
    a := 5  // 二进制: 0101
    result := a << 2
    fmt.Printf("%d << 2 = %d (binary: %b)\n", a, result, result)
}

5 左移 2 位,结果为 2010100)。

  1. 右移操作符(>>:将一个整数的二进制位向右移动指定的位数,对于无符号整数,左边空出的位用 0 填充;对于有符号整数,左边空出的位用符号位填充。例如:
package main

import "fmt"

func main() {
    a := 5  // 二进制: 0101
    result := a >> 1
    fmt.Printf("%d >> 1 = %d (binary: %b)\n", a, result, result)
}

5 右移 1 位,结果为 20010)。

赋值操作符

赋值操作符用于将一个值赋给一个变量。最基本的赋值操作符是 =,除此之外,Go语言还提供了复合赋值操作符,如 +=-=*=/=%=&=|=^=<<=>>= 等。

  1. 基本赋值操作符(=:例如:
package main

import "fmt"

func main() {
    var a int
    a = 5
    fmt.Printf("a = %d\n", a)
}

这里将 5 赋值给变量 a

  1. 复合赋值操作符:以 += 为例,它将变量自身与右边的值相加,并将结果重新赋给该变量。例如:
package main

import "fmt"

func main() {
    a := 5
    a += 3
    fmt.Printf("a += 3, now a = %d\n", a)
}

a 原来的值为 5,执行 a += 3 后,a 的值变为 8。其他复合赋值操作符的原理类似。

其他操作符

  1. 取地址操作符(&:用于获取变量的内存地址。例如:
package main

import "fmt"

func main() {
    a := 5
    addr := &a
    fmt.Printf("The address of a is %p\n", addr)
}

这里 &a 获取了变量 a 的内存地址,并通过 %p 格式化输出。

  1. 指针取值操作符(*:与取地址操作符相对,用于获取指针指向的值。例如:
package main

import "fmt"

func main() {
    a := 5
    addr := &a
    value := *addr
    fmt.Printf("The value at address %p is %d\n", addr, value)
}

这里 *addr 获取了指针 addr 指向的值,即 a 的值 5

  1. 类型断言操作符(.(type):用于在运行时断言一个接口值的具体类型。例如:
package main

import (
    "fmt"
)

func main() {
    var i interface{} = 5
    v, ok := i.(int)
    if ok {
        fmt.Printf("i is of type int and value is %d\n", v)
    } else {
        fmt.Printf("i is not of type int\n")
    }
}

这里通过 i.(int) 断言接口值 i 是否为 int 类型,如果是,则 oktrue,并将 i 的值赋给 v

Go语言分隔符

分隔符在Go语言中用于分隔代码中的不同元素,使代码结构更加清晰和易于理解。常见的分隔符有分号(;)、逗号()、冒号(:)、花括号({})、方括号([])和圆括号(())等。

分号(;

在Go语言中,分号通常用于分隔语句。不过,与其他语言不同,Go语言的编译器会自动插入分号,所以在大多数情况下,程序员不需要显式地写分号。例如:

package main

import "fmt"

func main() {
    a := 5
    b := 3
    result := a + b
    fmt.Println(result)
}

虽然这里没有显式的分号,但编译器会在每一行语句的末尾插入分号。不过,在某些情况下,需要注意分号的隐式插入规则,例如在 for 循环的初始化、条件和后置语句之间,不能换行,否则编译器可能会插入不正确的分号。例如:

package main

import "fmt"

func main() {
    for i := 0
         i < 5
         i++ {
        fmt.Println(i)
    }
}

这样写是错误的,因为编译器会在 i := 0 后插入分号,导致语法错误。正确的写法是:

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }
}

逗号(

逗号在Go语言中有多种用途。它用于分隔函数的参数、初始化多个变量、在切片和映射中分隔元素等。

  1. 分隔函数参数:例如:
package main

import "fmt"

func add(a, b int) int {
    return a + b
}

func main() {
    result := add(3, 5)
    fmt.Println(result)
}

这里 add 函数接受两个 int 类型的参数,用逗号分隔。

  1. 初始化多个变量:例如:
package main

import "fmt"

func main() {
    a, b := 3, 5
    fmt.Printf("a = %d, b = %d\n", a, b)
}

同时初始化 ab 两个变量,用逗号分隔。

  1. 在切片和映射中分隔元素:例如:
package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5}
    mapData := map[string]int{"one": 1, "two": 2, "three": 3}
    fmt.Println(slice)
    fmt.Println(mapData)
}

在切片和映射的初始化中,元素之间用逗号分隔。

冒号(:

冒号在Go语言中有以下几种主要用途:

  1. map 中分隔键值对:例如:
package main

import "fmt"

func main() {
    mapData := map[string]int{"one": 1, "two": 2, "three": 3}
    fmt.Println(mapData)
}

这里 : 用于分隔 map 中的键和值。

  1. 在类型声明中分隔类型和值:例如:
package main

import "fmt"

func main() {
    var a int = 5
    var b string = "hello"
    fmt.Printf("a is of type %T and value %d\n", a, a)
    fmt.Printf("b is of type %T and value %s\n", b, b)
}

在变量声明中,: 用于分隔变量类型和初始值(在简短声明中,:= 结合了声明和赋值)。

  1. switch 语句中分隔 case 标签和语句:例如:
package main

import "fmt"

func main() {
    num := 2
    switch num {
    case 1:
        fmt.Println("One")
    case 2:
        fmt.Println("Two")
    default:
        fmt.Println("Other")
    }
}

这里 : 用于分隔 case 标签和后续的语句。

花括号({}

花括号在Go语言中用于定义代码块,如函数体、循环体、if - else 块、switch 块等。

  1. 函数体:例如:
package main

import "fmt"

func add(a, b int) int {
    return a + b
}

func main() {
    result := add(3, 5)
    fmt.Println(result)
}

add 函数和 main 函数的函数体都用花括号括起来。

  1. 循环体:例如:
package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }
}

for 循环的循环体用花括号括起来。

  1. if - else:例如:
package main

import "fmt"

func main() {
    a := 5
    if a > 3 {
        fmt.Println("a is greater than 3")
    } else {
        fmt.Println("a is less than or equal to 3")
    }
}

ifelse 的代码块都用花括号括起来。

方括号([]

方括号在Go语言中主要用于定义数组和切片,以及访问它们的元素。

  1. 定义数组:例如:
package main

import "fmt"

func main() {
    array := [3]int{1, 2, 3}
    fmt.Println(array)
}

这里定义了一个长度为 3int 类型数组 array

  1. 定义切片:例如:
package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(slice)
}

定义了一个 int 类型的切片 slice。切片是动态数组,长度可以变化。

  1. 访问数组和切片元素:例如:
package main

import "fmt"

func main() {
    array := [3]int{1, 2, 3}
    slice := []int{4, 5, 6, 7, 8}
    fmt.Printf("array[1] = %d\n", array[1])
    fmt.Printf("slice[2] = %d\n", slice[2])
}

通过方括号加索引来访问数组和切片的元素。

圆括号(()

圆括号在Go语言中有多种用途:

  1. 函数调用:例如:
package main

import "fmt"

func add(a, b int) int {
    return a + b
}

func main() {
    result := add(3, 5)
    fmt.Println(result)
}

在调用 add 函数时,参数放在圆括号中。

  1. 表达式分组:例如:
package main

import "fmt"

func main() {
    result := (3 + 5) * 2
    fmt.Println(result)
}

通过圆括号改变表达式的运算优先级,这里先计算 3 + 5,再乘以 2

  1. 类型转换:例如:
package main

import "fmt"

func main() {
    a := 5.5
    b := int(a)
    fmt.Printf("a = %.2f, b = %d\n", a, b)
}

通过圆括号将 float64 类型的 a 转换为 int 类型。

通过深入理解Go语言的操作符和分隔符,开发者能够更加准确、高效地编写Go代码,充分发挥Go语言的优势。无论是简单的算术运算,还是复杂的逻辑判断和位操作,操作符都提供了强大的功能。而分隔符则确保了代码结构的清晰和可读性,使得Go代码易于维护和扩展。在实际编程中,熟练运用这些操作符和分隔符是成为优秀Go开发者的重要基础。