在 Go 中,变量被显式声明,并可以被编译器用来检查函数调用时的类型正确性。
// variables.go
package main
import "fmt"
func main() {
// `var` 声明 1 个或者多个变量。
var a = "initial"
fmt.Println(a)
// 你可以一次性声明多个变量。
var b, c int = 1, 2
fmt.Println(b, c)
// Go 将自动推断已经初始化的变量类型。
var d = true
fmt.Println(d)
// 声明后却没有给出对应的初始值时,变量将会初始化为
// _零值_ 。例如,一个 `int` 的零值是 `0`。
var e int
fmt.Println(e)
// `:=` 语法是声明并初始化变量的简写,例如
// 这个例子中的 `var f string = "short"`。
f := "short"
fmt.Println(f)
}
[root@bogon test]# go run variables.go
initial
1 2
true
0
short
[root@bogon test]#
简述变量(Variables)
变量是什么?
变量指定了某存储单元(Memory Location)的名称,该存储单元会存储特定类型的值。
在 Go 中,有多种语法用于声明变量。
声明单个变量
var name type
package main
import "fmt"
func main() {
var age int // 变量声明
fmt.Println("my age is", age)
}
在线运行程序
语句 var age int 声明了一个 int 类型的变量,名字为 age。我们还没有给该变量赋值。如果变量未被赋值,Go 会自动地将其初始化,赋值该变量类型的零值(Zero Value)。
my age is 0
变量可以赋值为本类型的任何值。
上一程序中的 age 可以赋值为任何整型值(Integer Value)。
package main
import "fmt"
func main() {
var age int // 变量声明
fmt.Println("my age is", age)
age = 29 // 赋值
fmt.Println("my age is", age)
age = 54 // 赋值
fmt.Println("my new age is", age)
}
在线运行程序
上面的程序会有如下输出:
my age is 0
my age is 29
my new age is 54
声明变量并初始化
声明变量的同时可以给定初始值。
var name type = initialvalue
package main
import "fmt"
func main() {
var age int = 29 // 声明变量并初始化
fmt.Println("my age is", age)
}
在线运行程序
在上面的程序中,age 是具有初始值 29 的 int 类型变量。
如果你运行上面的程序,你可以看见下面的输出,证实 age 已经被初始化为 29。
my age is 29
类型推断(Type Inference)
如果变量有初始值,那么 Go 能够自动推断具有初始值的变量的类型。
因此,如果变量有初始值,就可以在变量声明中省略 type。
var name = initialvalue
在下面的例子中,我们省略了变量 age 的 int 类型,Go 依然推断出了它是 int 类型。
package main
import "fmt"
func main() {
var age = 29 // 可以推断类型
fmt.Println("my age is", age)
}
声明多个变量
Go 能够通过一条语句声明多个变量。
var name1, name2 type = initialvalue1, initialvalue2
package main
import "fmt"
func main() {
var width, height int = 100, 50 // 声明多个变量
fmt.Println("width is", width, "height is", heigh)
}
在线运行程序
上述程序将在标准输出打印 width is 100 height is 50。
你可能已经想到,如果 width 和 height 省略了初始化,它们的初始值将赋值为 0。
package main
import "fmt"
func main() {
var width, height int
fmt.Println("width is", width, "height is", height)
width = 100
height = 50
fmt.Println("new width is", width, "new height is ", height)
}
width is 0 height is 0
new width is 100 new height is 50
在有些情况下,我们可能会想要在一个语句中声明不同类型的变量。
其语法如下:
var (
name1 = initialvalue1,
name2 = initialvalue2
)
使用上述语法,下面的程序声明不同类型的变量。
package main
import "fmt"
func main() {
var (
name = "naveen"
age = 29
height int
)
fmt.Println("my name is", name, ", age is", age, "and height is", height)
}
这里我们声明了 string 类型的 name、int 类型的 age 和 height。
运行上面的程序会产生输出 my name is naveen , age is 29 and height is 0。
简短声明
:=
name := initialvalue
package main
import "fmt"
func main() {
name, age := "naveen", 29 // 简短声明
fmt.Println("my name is", name, "age is", age)
}
my name is naveen age is 29
:=
下面程序将会抛出错误 cannot assign 1 values to 2 variables,这是因为 age 没有被赋值。
package main
import "fmt"
func main() {
name, age := "naveen" //error
fmt.Println("my name is", name, "age is", age)
}
:=
考虑下面的程序:
package main
import "fmt"
func main() {
a, b := 20, 30 // 声明变量a和b
fmt.Println("a is", a, "b is", b)
b, c := 40, 50 // b已经声明,但c尚未声明
fmt.Println("b is", b, "c is", c)
b, c = 80, 90 // 给已经声明的变量b和c赋新值
fmt.Println("changed b is", b, "c is", c)
}
由于 b 已经被声明,而 c 尚未声明,因此运行成功并且输出:
a is 20 b is 30
b is 40 c is 50
changed b is 80 c is 90
但是如果我们运行下面的程序:
package main
import "fmt"
func main() {
a, b := 20, 30 // 声明a和b
fmt.Println("a is", a, "b is", b)
a, b := 40, 50 // 错误,没有尚未声明的变量
}
no new variables on left side of := 的错误:=
变量也可以在运行时进行赋值。
考虑下面的程序:
package main
import (
"fmt"
"math"
)
func main() {
a, b := 145.8, 543.8
c := math.Min(a, b)
fmt.Println("minimum value is ", c)
}
在上面的程序中,c 的值是运行过程中计算得到的,即 a 和 b 的最小值。
上述程序会打印:
minimum value is 145.8
由于 Go 是强类型(Strongly Typed)语言,因此不允许某一类型的变量赋值为其他类型的值。
cannot use "naveen" (type string) as type int in assignment
package main
func main() {
age := 29 // age是int类型
age = "naveen" // 错误,尝试赋值一个字符串给int类型变量
}
指针变量访问其成员变量方式
通过指针变量p访问其成员变量name, 有哪几种方式?
A p.name
B (&p).name
C (*p).name
D p->name
参考答案: AC参考解析: &取址运算符,*指针解引用。