变量,翻译英文的是variable。
变量的声明格式是:var identifier type,也就是使用var关键字。
标准格式
Go语言的变量声明格式为:
var 变量名 变量类型
变量声明以关键字var开头,后置变量类型,行尾无须分号。
var a int
var b string
var c []float32
var d func() bool
var e struct{
x int
}
批量格式
var (
a int
b string
c []float32
d func() bool
e struct{
x int
}
)
使用关键字var和括号,可以将一组变量定义放在一起。
初始化变量
整型和浮点型变量的默认值为0 。
字符串变量的默认值为空字符串。
布尔型变量默认为bool。
切片、函数、指针变量的默认为nil。
标准格式
var 变量名 类型 = 表达式
下面代码:
package main
import(
"fmt"
"reflect" //检查变量的类型
"strconv" //类型转换
)
var (
a int
b string
c [2]float32
d func() bool //如果没有给布尔变量赋值,它将默认为false
e struct{
x int
}
)
func GetData()(int, int){
return 100, 200;
}
func main(){
x,_ := GetData() //no new variables on left side of :=
_,y := GetData()
fmt.Println(x, y)
a=100
b="Hello"
fmt.Println(a, b)
c[0]=1.2
c[1]=2.3
fmt.Println(c[0],c[1])
fmt.Println(reflect.TypeOf(e))
var t bool=true
fmt.Println(reflect.TypeOf(t))
var s string=strconv.FormatBool(true)
fmt.Println(reflect.TypeOf(s))
} //non-declaration statement outside function body
运行结果:
100 200
100 Hello
1.2 2.3
struct { x int }
bool
string
快捷变量声明
Go支持多种快捷变量声明方式。可在一行内声明多个类型相同的变量并给它们赋值。
快捷变量声明,程序清单如下:
package main //main.go:1:1: expected 'package', found 'EOF'
//上面有错误句子,解决方法是空一行。
import(
"fmt"
)
func main(){
var x, y string="Hello","World"
fmt.Println(x)
fmt.Println(y)
}
以快捷方式声明类型不同的变量,程序清单如下:
package main
import(
"fmt"
)
var(
x string="ciao"
y int=4
)
func main(){
fmt.Println(x)
fmt.Println(y)
}
/*
# command-line-arguments
./main.go:8:6: invalid character U+FF08 '(' in identifier
./main.go:9:7: syntax error: unexpected string at end of statement
./main.go:10:7: syntax error: unexpected int at end of statement
./main.go:11:3: invalid character U+FF09 ')' in identifier
douxiaobodemini:main douxiaobo$ go run main.go
*/
//上面出现错误,解决方法,不能在func main里面,而是在fanc main外面。
理解变量和零值
在Go语言中,声明变量时如果没有给它指定值, 则变量将为默认值,这种默认值被称为零值。
变量的零值,程序清单如下:
package main
import(
"fmt"
)
func main(){
var i int
var f float32
var b bool
var s string
fmt.Println("%v %v %v %q\n",i,f,b,s)
}
/*
# command-line-arguments
./main.go:8:9: undefined: float
*/
程序结果:
%v %v %v %q
0 0 false
使用变量时,知道Go语言的这种设计决策很重要。不久后,可能需要检查变量是否赋值。注意,在Go语言中,为确定变量是否已经赋值,不能检查它是否为nil,而必须检查它是否为默认值。由于类型string的零值为“ ”,因此对于类型为string的变量,要确定是否已经给它赋值,可检查其值是否为零值“ ”。
检查变量的值是否为零值,程序清单如下:
package main
import(
"fmt"
)
func main(){
var s string
if s==""{ //注意,双引号中间没有空格,否则,不会出现下面的句子。
fmt.Println("s has not been assigned a value and is zero valued")
}
}
简短变量声明,程序清单如下:
package main
import(
"fmt"
)
func main(){
s:="Hello World"
fmt.Println(s)
}
使用指针,程序清单如下:
package main
import(
"fmt"
)
func main(){
s:="Hello World"
fmt.Println(s)
fmt.Println(&s)
}
程序结果如下:
Hello World
0xc0000a0210
将变量作为值传递,将变量作为指针传递,程序清单如下:
package main
import(
"fmt"
)
func showMemoryAddress(x *int){
fmt.Println(x)
return
}
func main(){
i:=1
fmt.Println(i)
//showMemoryAddress(i) //error
fmt.Println(&i)
showMemoryAddress(&i)
}
程序结果如下:
1
0xc000096008
0xc000096008
使用指针指向的变量的值,程序清单如下:
package main
import(
"fmt"
)
func showMemoryAddress(x *int){
fmt.Println(*x) //带有*星号
return
}
func main(){
i:=1
fmt.Println(i)
fmt.Println(&i)
showMemoryAddress(&i)
}
程序结果如下:
1
0xc0000b2008
1
声明常量
常量指的是在整个程序生命周期内都不变的值。常量初始化后,可以引用它,但不能修改它。
package main
import(
"fmt"
)
const greeting string ="Hello, World!"
func main(){
fmt.Println(greeting)
}
变量赋值的代码如下:
package main
import(
"fmt"
)
func main(){
var a int
a=18
a=a+1
fmt.Println(a)
}
结果如下:
19
浮点数类型的变量的代码如下:
package main
import(
"fmt"
)
func main(){
var x,y float64
x=1.2
y=-3.31
fmt.Println(x*y)
}
运行结果如下:
-3.972
字符串类型的变量的代码如下:
package main
import(
"fmt"
)
func main(){
var a string
var b,c string
a="good"
b="morning"
c=a+" "+b
fmt.Println(c)
}
运行结果如下:
good morning
布尔类型的变量的代码如下:
package main
import(
"fmt"
)
func main(){
var a,b bool
a=true
b=!a
fmt.Println(b)
}
运行结果如下:
false
变量声明和赋值的简化形式的代码如下:
package main
import(
"fmt"
)
func main(){
var a float64
a=8.8
b:=10.1
fmt.Println(a+b)
}
Go语言中,把用“:=”操作符声明变量同时对其赋予初始值的操作称作“简化变量声明”(short variable declaration)或“简化声明”。
运行结果如下:
18.9
变量类型的转换
代码如下:
package main
import(
"fmt"
)
func main(){
var a int
var b int64
a=8
b=10
fmt.Println(a+int(b))
}
运行结果如下:
18
指针类型的变量的代码如下:
package main
import(
"fmt"
)
func main(){
var a int
a=10
fmt.Println(a)
var p *int
p=&a
*p=20
fmt.Println(a)
fmt.Println(*p)
fmt.Println(p)
}
“&”符号叫作“取地址符”,表示取得后面变量的地址。
运行结果如下:
10
20
20
0xc000016060
指向复合结构变量的指针的代码如下:
package main
import(
"fmt"
)
func main(){
var a []int
a=make([]int,3)
a[0]=1
a[1]=2
a[2]=3
fmt.Println(a)
var p *[]int
p=&a
(*p)[1]=8
fmt.Println(a)
fmt.Println(*p)
fmt.Println(p)
}
运行结果如下:
[1 2 3]
[1 8 3]
[1 8 3]
&[1 8 3]
变量的零值的代码如下:
package main
import(
"fmt"
)
func main(){
var a int
var b float64
var c string
var d bool
var e []int
var f map[string]float64
var g *int
var h *map[string]float64
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
fmt.Println(f)
fmt.Println(g)
fmt.Println(h)
}
运行结果如下:
0
0
false
[]
map[]
<nil>
<nil>
即使对于经验丰富的Go开发者,一个觉的陷阱,代码如下:
package main
import "fmt"
var x int = 10
func main() {
x := 1
fmt.Println(x)
{
fmt.Println(x)
x := 2
fmt.Println(x)
}
fmt.Println(x)
}
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go run main.go
1
1
2
1
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go>
package main
import "fmt"
func main() {
x := [3]int{1, 2, 3}
func(arr *[3]int) {
(*arr)[0] = 7
fmt.Println(arr)
}(&x)
fmt.Println(x)
}
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go run main.go
&[7 2 3]
[7 2 3]
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go tool compile -m main.go
main.go:11:13: inlining call to fmt.Println
main.go:9:14: inlining call to fmt.Println
main.go:7:7: leaking param: arr
main.go:6:2: moved to heap: x
main.go:7:2: func literal does not escape
main.go:9:14: []interface {}{...} does not escape
main.go:11:13: x escapes to heap
main.go:11:13: []interface {}{...} does not escape
<autogenerated>:1: leaking param content: .this
<autogenerated>:1: .this does not escape
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go>