常量包含不会发生更改的数据。常量的数据类型只能是boolean、number(int/float/complex)或string。html
定义方式:数据结构
const NAME [TYPE] = VALUE
TYPE基本能够省略,由于常量都是简单数据类型,编译器能够根据值推断出它的数据类型。闭包
例如:ide
const Pi = 3.14159
常量在编译期间被评估,所以定义的常量必须是在编译期间就能计算出来的结果。例如调用一些运行期间的函数来生成常量的值就是错误的,由于在编译期间没法调用这些运行期间的函数。常量的值定义好后,没法在运行期间更改,不然会报错。函数
const c = 3+2 // 正确 const d = getNumber() // 错误
常量的精度能够随意长,Go不会出现精度溢出的问题。且常量赋值时,若是值太长,可使用续行符\
:ui
const Ln2= 0.693147180559945309417232121458\ 176568075500134360255254120680009 const Log2E= 1/Ln2 const Billion = 1e9
Go中只有将超出变量精度的值赋值给变量时才会出现溢出问题。code
能够一次性定义多个常量:htm
const beef, two, c = "meat", 2, "veg" const Monday, Tuesday, Wednesday = 1, 2, 3 const ( Monday, Tuesday, Wednesday = 1, 2, 3 Thursday, Friday, Saturday = 4, 5, 6 )
常量能够用枚举。定义了下面的常量后,Female就表明了数值1。blog
const ( Unknown = 0 Female = 1 Male = 2 )
可使用iota
实现枚举,iota
自身是builtin包中定义的一个常量,其值为0,它用于在常量中定义序列数,从0开始增长:ip
const ( a = iota b = iota c = iota )
当iota
第一次调用时,产生数值0,在新行中再次调用iota,将自动增长1,因此上面的a=0,b=1,c=2
。上面的常量枚举能够简写成等价形式:
const ( a = iota b c )
iota不能用于运行期间,由于它是小写字母开头的常量,不会被导出。下面的代码会报错:iota未定义
var a int = iota
iota
也能够用于表达式中,例如iota+50
表示将当前的iota值加上50。
每一个常量块(const block)结构都会重置和初始化iota的值为0。
func main() { const a = iota // a=0 const b = iota + 3 // b=3 const c,d = iota,iota+3 // c=0,d=3 const ( e = iota // e=0 f = iota + 4 // f=5 g // g=6 ) println(a,b,c,d,e,f,g) }
在使用变量以前,有两个过程:声明变量、变量赋值。声明变量也常被称为"定义变量"。变量声明后必须使用,不然会报错。
定义变量的经常使用方式:
var identifier type
例如:
var a int var b bool var str string // 或者 var ( a int b bool str string )
当变量声明的时候,会作默认的赋0初始化,每种数据类型的默认赋0初始化的0值不一样。例如int类型的0值为数值0,float的0值为0.0,string类型的0值为空"",bool类型的0值为false,数据结构的0值为nil,struct的0值为字段所有赋0。
变量在编译期间就能够获取到它的值,但若是赋值给变量的值须要通过运行期间的计算,则须要延迟到运行期间才能获取对应的值。
var a int = 15 // 编译期间赋值好 var b int = 15/3 // 编译期间赋值好 var c = getNumber() // 运行期间才赋值
声明和赋值能够结合:
var a int = 15 var i = 5 var b bool = false var str string = "Hello World"
声明和赋值结合的时候,对于简单数据类型的值,能够省略type部分,由于Go能够根据值本身推断出类型:
var a = 15 var b = false var str = "Hello World" var ( a = 15 b = false str = "Hello World" numShips = 50 city string )
由于要推断数据类型,因此类型推断操做是在运行期间完成的。
在使用推断类型的赋值时,若是想要指定特定类型,须要显式指定。例如整数数值推断的类型为int,要想让它保存到int64中,则必须显式指定类型:
var a int64 = 2
要推断类型必须是声明和赋值一块儿的,不然没有值,没法根据值去推断。例如var a
是错的。
除了上面的推断方式,经过:=
符号也能实现声明和赋值结合,它也会根据数据类型进行推断,连var关键字都省略了:
a := 50
可是:=
只能在函数代码块内部使用,在全局做用域下使用将报错,由于类型推断是在运行期执行的,而全局范围内的变量声明部分是在编译期间就决定好的。例如,下面的将报错:
a := 10 func main() { println(a) }
变量声明以后不能再次声明(除非在不一样的做用域),以后只能使用=
进行赋值。例如,执行下面的代码将报错:
package main import ("fmt") func main(){ x:=10 fmt.Println("x =",x) x:=11 fmt.Println("x =",x) }
错误以下:
# command-line-arguments .\test.go:8:3: no new variables on left side of :=
报错信息很明显,:=
左边没有新变量。
若是仔细看上面的报错信息,会发现no new variables
是一个复数。实际上,Go容许咱们使用:=
一次性声明、赋值多个变量,并且只要左边有任何一个新变量,语法就是正确的。
func main(){ name,age := "longshuai",23 fmt.Println("name:",name,"age:",age) // name从新赋值,由于有一个新变量weight weight,name := 90,"malongshuai" fmt.Println("name:",name,"weight:",weight) }
须要注意,name第二次被:=
赋值,Go第一次推断出该变量的数据类型以后,就不容许:=
再改变它的数据类型,由于只有第一次:=
对name进行声明,以后全部的:=
对name都只是简单的赋值操做。
例如,下面将报错:
weight,name := 90,80
错误信息:
.\test.go:11:14: cannot use 80 (type int) as type string in assignment
另外,变量声明以后必须使用,不然会报错,由于Go对规范的要求很是严格。例如,下面定义了weight
但却没使用:
weight,name := 90,"malongshuai" fmt.Println("name:",name)
错误信息:
.\test.go:11:2: weight declared and not used
Go语言的做用域采用的是词法做用域,意味着文本段定义所在位置决定了可看见的值范围。关于词法做用域和动态做用域,详细内容参见:一文搞懂:词法做用域、动态做用域、回调函数、闭包
{...CODE...}
)的变量也是局部变量,除了代码块就消失不一样scope的变量名能够冲突,但建议采起名称惟一的方式为变量命名。