Go 语言变量

声明、多变量、短声明、作用域与遮蔽、以及值语义。

Beginner
Key PointsGo 的变量是值语义:赋值和传参都是复制,指针才共享。

声明与赋值

Go
var a int          // 声明,零值 0
a = 10             // 赋值

var b int = 20     // 声明 + 初始化
var c = 30         // 类型推断

d := 40            // 短声明(函数内)

a, b = b, a        // 交换,不需要临时变量
fmt.Println(a, b, c, d)
Output
20 10 30 40

多变量

Go
var x, y int = 1, 2
var p, q = 3, "四"

// 用 _ 丢弃不想要的值
_, err := fmt.Println("返回值个数")
fmt.Println(err)

// 函数多返回值
func minMax(a []int) (int, int) { ... }
lo, hi := minMax([]int{3, 1, 4})

作用域与遮蔽

Go
x := 1
fmt.Println("外层", x)

{
	x := 2                 // 新的 x,遮蔽外层
	fmt.Println("内层", x)
}

fmt.Println("外层还是", x)

if x := 99; x > 10 {
	fmt.Println("if 里", x)  // 只在 if 块内有效
}
// fmt.Println(x)          // 这里仍是 1
Output
外层 1
内层 2
外层还是 1
if 里 99
The dangerous case is err: := inside an if creates a new err, leaving the outer one nil and silently swallowing the error. go vet's shadow check catches it.

值语义

Go
type Point struct{ X, Y int }

p1 := Point{1, 2}
p2 := p1          // 复制一份
p2.X = 100
fmt.Println(p1, p2)

// 想共享就传指针
p3 := &p1
p3.X = 200
fmt.Println(p1)
Output
{1 2} {100 2}
{200 2}

Slices, maps and channels are value types but hold pointers internally, so after assignment the underlying data is shared. This trips up most Go beginners.

Go
a := []int{1, 2, 3}
b := a
b[0] = 99
fmt.Println(a, b)     // 都变了
Output
[99 2 3] [99 2 3]

Friends & Partners