程序语言中的最简单的第一步认识,就是认识如何定义变量。 往往程序语言处理的第一个动作会是从定义变量开始。而本文就主要要说明golang当中有几种声明变量的方式。及几种方式的差异。
变量声明方式:
- 完整的变量声明。 var name type // var i int
- 声明并初始值 var name type = value // var name string = 'liwentong'
- 自动类型推断 var name = value // var name = 'string'
- 声明多变量 var name1,name2 = 'liwentong1','liwentong2'
- 简短声明: name2 := 'string'
这里几种声明方式,都有需要注意的特性。
变量是什么?
变量是用来定位一个存储特定类型的值的内存地址。在Go语言中有多种声明变量的语法。
完整声明变量
只声明变量,没有进行初始值。而被声明出来的变量,会自动初始化为对应类型的零值。其中int 为0 string 为‘’ 其他为nil。而对于一部分类型的变量,需要进行初始化赋值之后,才能够进行使用。有些特殊类型的声明和初始化,需用专有的方式进行初始化。入make函数就专门用户map,slice,chan的声明初始化。
完整声明变量适用于常规变量声明。
package main
import "fmt"
func main() {
var age int // 变量声明
fmt.Println("my age is", age)
}
声明并初始化
package main
import "fmt"
func main() {
var age int = 29 // 声明变量并初始化
fmt.Println("my age is", age)
}
类型推断
类型推断:类型推断是一种编程语言在编译期间自动 解释表达式类型的能力。
如果变量有初始值,那么 Go 能够自动推断具有初始值的变量的类型。因此,如果变量有初始值,就可以在变量声明中省略 type。
如果变量声明的语法是 var name = initialvalue,Go 能够根据初始值自动推断变量的类型。
package main
import "fmt"
func main() {
var age = 29 // 可以推断类型
fmt.Println("my age is", age)
}
声明多个变量
Go 能够通过一条语句声明多个变量。必须给多个变量都进行赋值。不应该只对其中一个变量进行赋值。
package main
import "fmt"
func main() {
var width, height int = 100, 50 // 声明多个变量
fmt.Println("width is", width, "height is", heigh)
}
只声明多个变量,未初始化。同样变量会自动被初始化为类型零值。
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)
}
在一个语句中声明多个不同类型的变量
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)
简短声明
Go 也支持一种声明变量的简洁形式,称为简短声明(Short Hand Declaration),该声明使用了 := 操作符。声明变量的简短语法是 name := initialvalue。在简短声明当中,同样也会自己进行类型推断。 短变量其实就是类型推断再加上一点点语法糖。
需要注意的点:
- 声明的变量需要未被声明过
- 多个变量声明时,需要都赋值
多个变量的简短声明示例:
package main
import "fmt"
func main() {
name, age := "naveen", 29 // 简短声明
fmt.Println("my name is", name, "age is", age)
}
错误的方式
package main
import "fmt"
func main() {
name, age := "naveen" //这里是错误的
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)
a,c := 100,10 //此处会报错。
}
表达式初始化
在声明初始化的时候,右侧赋的值是一个表达式。 变量是当作一个程序实体。而golang编译器对程序实体进行赋值的时候。编译器是需要能够明确出变量的具体类型,才能进行编译赋值。在进行表达式赋值的时候,就要求表达式最终是能够给出一个具体的变量类型的。
package main
import "fmt"
func addNum(a,b int) int {
return a+b
}
func main(){
a,b := 1,2
var c = addNum(a,b) //等号左边就是表达式。c是一个程序实体。在对程序实体赋值对时候。golang编译器是需要能够明确出来变量类型对。而如果
fmt.Print(c)
}
变量重声明
在使用简短变量声明的时候。我们有提到一点在进行多个变量简短变量声明的时候。需要左侧的其中一个变量是未被声明的。那如果其中一个是已经被声明过的变量呢? 如何对待这个变量。这就重复又做了一次变量声明。这就是变量重声明。
重声明的必要条件:
- 重声明的类型与原有类型是一致的。
- 重声明只能使用短声明的方式,进行重声明。
- 重声明发生在当前代码快。而除此本代码块的重声明,就需考虑作用于范围。
//变量重声明的作用域问题
JCdeMacBook-Pro:tmp jcgroup$ more test.go
package main
import "fmt"
func addNum(a,b int) int {
return a+b
}
func main(){
var a int
a,b := 1,2
var c = addNum(a,b)
if b != 0 {
a := 32 //在此代码块中重声明,那表示在此代码块中,对a重新进行了声明。此会覆盖此代码块外的a=2的声明。并且此时a的作用域,也仅在此代码块中。
fmt.Println(a)
}
fmt.Println(a) //此处的a,是外层的变量a。 a=1。
fmt.Println(c)
}
JCdeMacBook-Pro:tmp jcgroup$ go run test.go
32
1
3
小结:
- 变量完整类型声明:给定完整的变量完整的类型。
- 变量声明并初始化:初始化声明变量会自动推断变量类型。
- 多变量声明:同时声明多个变量。必须均给多个变量赋值。
- 类型推断:声明初始化时未给定变量类型,将编译时自动推断变量类型。
- 简短声明:通过:=对变量进行声明和初始化。同样会进行类型推断。简短声明需要满足一些基本的条件。必须包含一个未被定义的变量。
- 表达式声明:变量初始化右侧可以是一个表达式。但表达式必须能够在编译时最终被求值。确定类型。
- 变量重声明: 变量重声明使用简短声明方式。且被重声明变量必须是未被定义。在其他代码块中重声明需考虑作用域范围。
参考链接: