0%

Go基础之变量

在Go语言中只存在值类型。

Go语言的变量都有相应的类型,必须经过声明才能使用。

声明变量

标准格式:

1
var 变量名 变量类型

当声明的变量较多时也可以使用批量格式:

1
2
3
4
5
6
7
8
9
var (
a int
b string
c []float32
d func() bool
e struct {
x int
}
)

内建变量类型

  • bool 布尔类型
  • string 字符串类型,实际上是一个[]byte字节数组。
  • 整数 (u)int (u)int8 (u)int16 (u)int32 (u)int64 uintptr 其中,int为不规定长度的整型,根据操作系统的位数决定,ptr在Go语言中是指针的意思,指针的长度也是跟着操作系统决定的
  • byte ,rune ,其中byte是8位的,rune是Go语言的char字符类型,不同于其他语言的1字节8位,rune是4字节32位的,实际上是int32的别名,可以混用。
  • 浮点型 float32, float64 ,complex64, complex128 ,后面两者为复数,complex64的实部和虚部分别为float32位,complex128的实部和虚部分别为float64位。

Golang中严格区分单引号'和双引号",前者用来表示单个字符,后者用于表示字符串

强制类型转换

  • 类型转换是强制的,没有隐式的转换,即转换的时候要使用int()这样进行强制转换

初始化变量值

Go在声明变量的时候,自动对变量的内存区域进行初始化操作,即变量在初始化时没有进行赋值的情况下,类型会有相应的默认值。

  • 整型和浮点类型的默认值为0
  • 字符串变量的默认值为空字符串类型
  • 布尔类型的默认值为bool
  • 切片、函数、指针变量的默认值为nil

Go语言的变量要求相当严格,要求函数内的变量一旦定义了,就必须使用到,否则报错。但是对于函数外的变量没有要求,是可以定义了但是没有被使用。

函数外的变量

Go语言中在函数外的变量不是全局变量,而是叫包内变量,因为Go语言文件都是包内(package main),没有全局变量的说法,在包内的变量需使用var进行声明,且可以声明了不被使用。

函数外的变量(即包内的变量)是可以在函数内部使用的。

标准格式

1
2
var 变量名 类型 = 表达式
var hp int = 100

编译器推导类型的格式

在标准格式的基础上,将int省略后,编译器会尝试根据等号右边的表达式推导出变量的类型

1
2
var 变量名 = 表达式
var hp = 100

此时,就会根据2的类型,自动推导出变量名hp的类型为int类型。

短变量声明并初始化 – 只限在函数内使用

var的变量声明还有更为精简的写法,例如

1
hp := 100

该写法为推导写法,编译器会自动根据右值类型推断出左值得对应类型

  • 注意:由于使用类":=",而不是赋值的"=",因此推导式左边的变量必须是没有定义过的变量。若是定义过得或报错。如:
1
2
3
4
5
6
7
8
9
10
package main

import "fmt"

func main(){
var hp int
hp := 100
fmt.Println(hp)
}
// 此时会报错:no new variables on left side of :=
  • 短变量声明的时候要求左边必须是新值,但是若左边有多个值的时候,此时只要在含有新的值得情况下,其他的值即使是重复的也没有问题。
    综上,使用短变量必须是对新变量,完成新变量的声明和赋值。
  • 注意:若使用短变量声明模式,需在函数内使用,若在函数之外,必须使用var关键字

在函数内命名和包内变量同名的变量,实际上是创建了新的函数内变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

var a int = 1
var b int = 1

func main(){
a := 3 // 此处的a是函数内部的变量,而函数外的包内变量a没有关系
b = 3 // 此处的b是函数外的包内变量在函数内进行调用
fmt.Println("函数变量a", a) // 3
fmt.Println("函数变量b,实际上是包内变量", b) //3
outerVar()

}

func outerVar(){
fmt.Println("包内变量a", a) //1
fmt.Println("包内变量b", b) //3
}

变量交换

使用Go语言的”多重赋值”的特性,可以轻松完成变量交换的任务

1
2
3
4
a := 100
b := 200

b,a = a,b

匿名变量

使用“_”来代替接受值

常量 – Go中的常量不要求要大写表示

Go中的大小写有相应的含义,所以对于常量是不要求全部用大写展示的。

常量可以作为各种类型去使用

1
2
3
const a,b = 3,4
var c int = int(math.Sqrt(a*a+b*b))
// 原先要求math.Sqrt中的参数要为float64类型,但是由于使用const定义常量的时候没有使用类型,此时调用的时候ab可以是任何类型,相当于直接贴值过来的,当然也可以规定类型为float64,否则报错

Go语言对于类型有严格的要求,如上面的math.Sqrt()函数要求参数类型必须是float64类型,此时传递float32都是不行的。

枚举类型

  • 注意一定要在const块中来声明

  • iota专门用在常量的声明中,其初始值为0,且当一组值同时声明的时候,其会自增长。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "fmt"

func main(){
const (
a = iota // 0
b = iota // 1
c = 3
d = iota // 3 这里要注意,iota是逐行增加的,即使没有使用
)
const( // 像下面的声明中cpp会为0 之后的变量可以不进行手动赋值,会自动增值赋值
cpp = iota
_
python
java
golang
)
const e = iota // 0
const f = iota // 0 这里由于不是在一个组内进行声明,所以都是0

fmt.Println(a,b,c,d,e,f) // 0 1 3 3 0 0
const (
b = 1 << (10 * iota)
kb
mb
gb
tb
pb
)
fmt.Println(b,kb,mb,gb,tb,pb) // 1 1024 1048576 1073741824 1099511627776 1125899906842624
}

lota 可以作为种子,帮助完成自增

布尔类型

为bool类型,但是bool类型是不可以和整型进行相互转换的,声明布尔类型在没有赋值的情况下,默认的值为false

1
2
3
4
5
// 声明方式一
var a bool
a = ture
// 或者
a := true

打印函数

Println和Printf的区别:Println用于打印字符串和变量,Printf只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

func variableZeroValue(){
var a int // 变量名在类型之前
var s string
fmt.Printf("%d %q",a, s) // %q的作用是 显示用单引号围绕该值,因为string类型的默认值为空字符串,这样显示会更加直观一些

}
func main() {
fmt.Println("hello world")
variableZeroValue()
}

变量定义的要点

  • 变量类型写在变量名之后

  • 编译器可推测变量类型

  • 没有char,只有rune,而且是32位的,可以作为是int32的别名

  • 原生支持复数类型

  • 变量一旦指定类型了,就不能接受其他类型的赋值(这点和Python不一样,Python中变量名只是标签)

    1
    2
    3
    4
    s := "Y" // UTF-8
    s = 1
    fmt.Println(s)
    // cannot use 1 (type int) as type string in assignment