Go-变量和常量

变量

变量定义的标准格式为:变量声明以关键字 var 开头,后置变量类型,行尾不加分号。

1
2
3
4
5
6
7
8
9
10
11
12
//var 变量名 变量类型
var name type

// go 语言支持同时定义多个相同类型的变量
// var 变量名1 变量名2 变量类型
var name1 name2 type

// 批量定义变量
var (
name string
age int
)

当一个变量被声明之后,如果没有显式的给它赋值,系统自动赋予它该类型的零值:

类型 默认值
整型 0
浮点型 0.0
字符串 空字符串
布尔型 false
切片、函数、指针变量 nil

变量初始化

短变量声明并初始化:(只能使用在函数内部)

1
2
3
4
5
6
7
8
9
10
11
12
package main
import "fmt"

func main() {
// := 自动推导
name := "jack"
age := 18

fmt.Println(name, age)
// 打印变量类型
fmt.Printf("%T,%T", name, age)
}

变量地址

1
2
3
4
5
6
7
8
9
10
11
12
package main
import "fmt"

func main() {
var num int
num = 100
fmt.Printf("num = %d,内存地址:%p\n", num, &num)

num = 200
fmt.Printf("num = %d,内存地址:%p", num, &num)

}

变量交换

1
2
3
4
5
6
7
8
9
package main
import "fmt"

func main() {
a := 100
b := 200
a, b = b, a
fmt.Println(a, b)
}

匿名变量

匿名变量的特点是一个下划线 “_” ,”_” 本身就是一个特殊的标识符,被称为空白标识符。它可以像其它标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变量对其它变量进行赋值或运算。使用匿名变量时,只需要在变量声明的地方使用下划线替换即可。例如:

1
2
3
4
5
6
7
8
9
10
11
12
package main
import "fmt"

func test01() (int, int) {
return 100, 200
}

func main() {
a, _ := test01() // 只获取第一个返回值
_, b := test01() // 只获取第二个返回值
fmt.Println(a, b)
}

变量的作用域

局部变量

在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,函数的参数和返回值变量都属于局部变量。

全局变量

在函数体外声明的变量称之为局部变量,全局变量只需在一个源文件中定义,就可以在所有源文件中使用,当然,不包含这个全局变量的源文件需要使用 “import” 关键字引入全局变量所在的源文件之后才能使用这个全局变量。

全局变量声明必须以 var 关键字开头,如果想要在外部包中使用全局变量的首字母必须大写。

全局变量和局部变量名称可以相同,但是函数体内的局部变量会被优先考虑。(就近原则)

常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是 布尔型、数字型(整数型、浮点型和复数)和字符串型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//显式类型定义
const a string = "hello,world!"

//隐式类型定义
const b = "hello,world!"

//多个相同类型的声明
const c_name1, c_name2 = value1, value2

//批量定义常量

const(
d = "haha"
e = "hey"
f // f 的值为"hey"
g // g 的值为"hey"
)
/*
一组常量中,如果某个常量没有初始值,默认和上一行一致
*/

iota

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

iota 在 const 关键字出现时将被重置为 0 (const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次 (iota 可理解为 const 语句块中的行索引)。

第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:

1
2
3
4
5
const (
a = iota
b
c
)

iota 用法

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
package main

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //独立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢复计数
            i          //8
    )

const (
a2 = iota //0,因为 const 关键字出现时 iota 被重置为0
b2
c2
)
    fmt.Println(a,b,c,d,e,f,g,h,i)
// 0 1 2 ha ha 100 100 7 8

fmt.Println(a2,b2,c2)
// 0,1,2
}

再看个有趣的的 iota 实例:

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
package main

import "fmt"
const (
    i=1<<iota
    j=3<<iota
    k
    l
)

func main() {
    fmt.Println("i=",i)
    fmt.Println("j=",j)
    fmt.Println("k=",k)
    fmt.Println("l=",l)
}
/*
i= 1
j= 6
k= 12
l= 24
iota 表示从 0 开始自动加 1,所以 i=1<<0, j=3<<1(<< 表示左移的意思)k=3<<2,l=3<<3
简单表述:
i=1:左移 0 位,不变仍为 1。
j=3:左移 1 位,变为二进制 110,即 6。
k=3:左移 2 位,变为二进制 1100,即 12。
l=3:左移 3 位,变为二进制 11000,即 24。
*/