• 周五. 11 月 13th, 2026

Go语言表达式

由root

10 月 13, 2019 #Golang

3.2 运算符

除位移操作外,操作数类型必须相同。如果其中一个是无显式类型声明的常量,那么该常量操作数会自动转型。
位移右操作数必须是无符号整数,或可以转换的无显式类型常量
自增,自减不再是运算符。只能作为独立的语句,不能用于表达式
func main() {
    a := 1
    ++a //语法错误。unexpected ++ (不能前置)
    if (a++) > 1 {  //语法错误: unexpected++, expecting) 语句不能作为表达式使用
    p := &a
    *p++    //相当于(*p)++
    println(a)
    }
}
指针: 不能将内存地址与指针混为一谈
内存地址是内存中每个字节单元的唯一编号,而指针则是一个实体。指针会分配内存空间,相当于一个专门用来保存地址的整型变量
  • &用于获取对象地址
    • 间接引用目标对象
  • 二级指针*T,如包含包名则写成package.T
可通过unsafe.Pointer将指针转换为uintptr后进行加减法远算。但可能会造成非法访问.
Pointer类似C语言中的void*万能指针,可用来转换指针类型。它能安全持有对象或对象成员,但uintptr不行。后者仅是一种特殊类型,并不引用目标对象,无法阻止垃圾回收器回收对象内存

3.3 初始化

对复合类型(数组,切片,字典,结构体)变量初始化时,有一些语法限制
  • 初始化表达式必须含类型标签
  • 左花括号必须在类型尾部,不能另起一行
  • 多个成员初始值以逗号分隔
  • 允许多行,但每行须以逗号或右花括号结束
正确示例
type data struct {
    x int
    s string
}
var a data = data{1, "abc"}

b := data {
    1, 
    "abc",
}

c := []int {
    1, 
    2 }

d := []int{1, 2,
    3, 4,
    5,
}

3.4 流控制

if…else…
if x > 5 {
    println("a")
} else if x < 5 && x > 0 {
    println("B")
} else {
    println("z")
}

if xinit(); x==0 {  //优先执行xinit函数
    println("a")
}

if a, b := x+1, x+10; a<b { //定义一个或多个局部变量
    println(a)
} else {
    println(b)
}
死代码是指永远不会被执行的代码,可使用专门的工具,或用代码覆盖率(code coverage)测试进行检查。
switch
func main() {
    a, b, c, x := 1, 2, 3, 2
    switch x {
        case a, b:  //多个匹配条件命中其一即可(OR),变量
            println("a | b")
        case c:
            println("c")
        case 4:
            println("d")
        default:
            println("z")
    }
}
相邻的空case不构成多条件匹配
switch x {
    case a: //单条件, 内容为空。隐式"case a: break;"
    case b:
        println("b")
}
不能出现重复的case常量值
无须显式执行break,如须贯通后续case须执行fallthrough,但不再匹配后续条件表达式
fallthrough必须放在case块结尾,可使用break语句阻止.
for
for i:=0; i<3; i++ {
    
}
for x<10 {
    
}
for {
    
}
for…range完成数据迭代,支持字符串,数组,数组指针,切片,字典,通道类型,返回索引,键值数据
注意, range会复制目标数据。受直接影响的是数组,可改用数组指针或切片类型
func main() {
    data := [3]int{10, 20, 30}
    for i, x := range data {            //从data复制品中取值
        if i == 0 {
            data[0] += 100
            data[1] += 200
            data[2] += 300
        }
        fmt.Printf("x:%d, data:%d\n", x, data[i])
    }
    for i, x := range data[:] {  //仅复制slice,不包括底层array
         if i == 0 {
            data[0] += 100
            data[1] += 200
            data[2] += 300
        }
        fmt.Printf("x:%d, data:%d\n", x, data[i])
    }
}
建议嵌套循环不要超过2层,否则会难以维护。必须时可剥离,重构为函数。
goto,continue,break
使用goto前,须先定义标签。标签区分大小写,且未使用的标签会引发编译错误
func main() {
    start:      //label start defined and not used
        for i:=0; i<3; i++ {
            println(i)
            if i>1 {
                goto exit
            }
        }
    exit:
        println("exit.")
}
break; 用于switch,for,select语句,终止整个语句块执行
continue; 仅用于for循环,终止后续逻辑,立即进入下一轮循环

由 root

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注