Go语言学习笔记-03变量
数据类型
- 布尔型,bool
- 无符号整形,uint,uint8,unit16,uint32,uint64
- 有符号整形,int,int8,int16,int32,int64
- 浮点型,float32,float64
- 复数型,complex64,complex128
- 字符串,string,表示Unicode字符序列
其他数字类型
byte,uint8的别名,表示单字节字符
rune,int32的别名,表示一个Unicode码点
uintptr,大到足够保存任何指针类型的整形类型
派生类型
数组类型,[n]T,表示元素类型为 T 的 n 个元素的数组的类型
切片类型,[]T,表示元素类型为 T 的可变长度数组的类型
map类型,键值对的无序集合,类似于其他语言中的字典或哈希表
结构化类型(struct),由多个字段组成的自定义数据类型
channel类型,用于在goroutine之间进行同步通信
指针类型(Pointer),*T
函数类型,func
接口类型(interface),表示实现特定方法的类型的类型
变量的声明
go是静态类型语言,声明变量时需要确定好变量的数据类型,不能在同一作用域中声明同名变量
声明有以下几种方式
- 仅声明不赋值
var 变量名 数据类型
- 声明同时赋值
var 变量名 数据类型 = 值
声明时缺省变量类型。
go编译器会根据右边值,自动推导默认类型,若默认类型不是想要的类型,则可以显式类型转换
var 变量名 = 值
var 变量名 = 值
var 变量名 = 数据类型(值)
- 同时申明多个变量
var (
变量名1 数据类型1
变量名2 数据类型2
)
var (
变量名1 数据类型1 = 值1
变量名2 数据类型2 = 值2
)
- 同一行同时声明多个变量
// 数据类型一致
var 变量名1, 变量名2 数据类型
var 变量名1, 变量名2 数据类型 = 值1, 值2
// 数据类型不一致,采用缺省数据类型方式
var 变量名1, 变量名2 = 值1, 值2
短变量声明,相当于声明一个变量并赋值
只能在函数体中使用
go编译器会根据右边的值,自动推导默认类型,若默认类型不是想要的类型,则可以显式类型转换
变量名 := 值
变量名 := 数据类型(值)
变量名1, 变量名2 := 值1, 值2
变量的赋值
go语言中,类型不同的变量不能赋值给对方,如int32
的变量,不能直接赋值给int
的变量
空白标识符
空白标识符也称为匿名占位符,使用_
表示
在 Go 语言中, 不允许声明未使用的变量或导入语句,这时可以使用空白标识符忽略掉
全局变量
在函数体外声明的变量是全局变量,也称为包级变量
只能使用var
方式申明,无法使用短变量声明方式
package main
// 全局变量
var 变量名 数据类型
var 变量名 = 值
var (
变量名1 = 值1
变量名2 = 值2
)
func main() {
}
代码示例
ch03/main.go
package main
// 全局变量声明
var globalA1 int
var globalB1 = 1
var (
globalC1 = 1
globalC2 = 1
)
func main() {
// 指定变量类型,没有初始化
var a1 int
// 声明并初始化
var b1 int = 1
// 变量声明块,批量声明多个变量
var (
c1 int = 128
c2 int8 = 6
c3 string = "hello"
c4 rune = 'A'
c5 bool = true
)
// 在一行同时声明多个变量
var d1, d2, d3 int = 1, 2, 3
// 在一行同时声明多个变量,类型不一致
var (
e1, e2, e3 = "e1", 2, 3.0
)
// 省略类型信息的声明,类型为默认类型
var f1 = 1 // int
var f1_1 = int32(1) // int32
var f2 = 1.1 // float64
var f3 = 'c' // int32
var f4 = "d" // string
var f5 = true // bool
// 短变量声明,申明并赋值,只能在函数体中使用
// 相当于
// var a int
// a = 12
g1 := 12
g2 := 'A'
g3 := "hello"
g4, g5, g6 := 12, 'A', "hello"
// 使用空白标识符_忽略掉未使用的变量
_ = globalA1
_ = globalB1
_, _ = globalC1, globalC2
_ = a1
_ = b1
_, _, _, _, _ = c1, c2, c3, c4, c5
_, _, _ = d1, d2, d3
_, _, _ = e1, e2, e3
_, _, _, _, _, _ = f1, f1_1, f2, f3, f4, f5
_, _, _, _, _, _ = g1, g2, g3, g4, g5, g6
// 当有新变量申明时,需要使用短变量声明方式
_, h7 := 0, 0
_ = h7
}
fmt包
fmt包主要用于向外输出内容和获取输入内容
Println
打印多个值并换行
ch03/fmt/main.go
package main
// 导入fmt包的包路径
import "fmt"
func main() {
fmt.Println(1, 2, 3)
fmt.Println(4, 5, 6)
}
上述代码输出
1,2,3
4,5,6
Printf
格式化输出,通过不同的占位符控制输出格式
常用占位符
占位符 | 说明 |
---|---|
%v | 值的默认格式表示 |
%+v | 类似%v,但输出结构体时会添加字段名 |
%#v | 值的Go语法表示 |
%T | 打印值的类型 |
%% | 百分号 |
%d | 打印整数 |
%c | 打印对应unicode码值 |
%s | 打印字符串或[]byte |
%f | 打印浮点数 |
%t | 打印布尔类型 |
ch03/fmt/main.go
package main
import "fmt"
func main() {
var a1 = 1
var a2 = 'a'
var a3 = true
fmt.Printf("%d %c %t", a1, a2, a3)
}
上述代码输出
1 a true
默认类型
缺省指定类型时,go会根据右值自动推导其数据类型
值 | 类型 | 备注 |
---|---|---|
整数 | int | 当数值不在int所能表示的范围内,则需要显式指定数据类型 |
浮点数 | float64 | |
字符 | rune | int32的别名,与int32等价 |
字符串 | string | |
true,false | bool |
ch03/defaulttype/main.go
package main
import "fmt"
func main() {
var a = 1
var b = 1.1
var c = 'a'
var d = "abc"
var e = true
fmt.Printf("变量a的类型为%T\n", a)
fmt.Printf("变量b的类型为%T\n", b)
fmt.Printf("变量c的类型为%T\n", c)
fmt.Printf("变量d的类型为%T\n", d)
fmt.Printf("变量e的类型为%T\n", e)
}
上述代码输出
变量a的类型为int
变量b的类型为float64
变量c的类型为int32
变量d的类型为string
变量e的类型为bool
零值
当只声明不赋值时,不同数据类型的变量会赋予其对应的零值
零值使得变量可以开箱即用,无需显示初始化,即零值可用
内置原生类型 | 默认值 | 零值是否可用 |
---|---|---|
所有整形类型 | 0 | 是 |
浮点类型 | 0.0 | 是 |
布尔类型 | false | 是 |
字符串类型 | "" | 是 |
指针、接口、切片、channel、map和函数类型 | nil | 否 |
struct | 各字段对应类型的零值 | 看具体字段的类型 |
数组 | 填充对应类型的零值 | 是 |
例子
ch03/zerovalue/main.go
package main
import "fmt"
func main() {
var var1 int
var var2 float32
var var3 bool
var var4 string
var var5 byte
var var6 [5]int
var var7 chan int
var var8 map[string]int
var var9 []int
var var10 func() int
// 注意有些是用%v,有些是用%#v
fmt.Printf("int的零值为%v\n", var1)
fmt.Printf("float32的零值为%v\n", var2)
fmt.Printf("bool的零值为%v\n", var3)
fmt.Printf("string的零值为%#v\n", var4)
fmt.Printf("byte的零值为%v\n", var5)
fmt.Printf("[5]int的零值为%v\n", var6)
fmt.Printf("[]int的零值为%#v\n", var9)
fmt.Printf("chan int的零值为%#v\n", var7)
fmt.Printf("map的零值为%#v\n", var8)
fmt.Printf("func() int的零值为%#v\n", var10)
}
上述代码输出
int的零值为0
float32的零值为0
bool的零值为false
string的零值为""
byte的零值为0
[5]int的零值为[0 0 0 0 0]
[]int的零值为[]int(nil)
chan int的零值为(chan int)(nil)
map的零值为map[string]int(nil)
func() int的零值为(func() int)(nil)
可以看出默认值为nil的数据类型类型不是单纯的nil,而是带有具体数据类型的nil,它们是不等价的
作用域
在go语言中,{}
包括的内容称之为一个代码块,可以嵌套,外层代码块的作用域包括所有内层代码块,换言之,外层代码块的变量可以在内层代码块内使用,在内层代码块定义与外层代码块同名的变量,会遮蔽外层代码块的同名变量,这种现象称之为变量遮蔽
除了有显示代码块,还有隐式代码块,包括if
,for
,switch
例子
ch03/variablemasking/main.go
package main
import "fmt"
var a = 1
func main() {
{
// 遮蔽包级变量a
a := 2
fmt.Println(a) // 2
}
if a := 3; a == 3 {
fmt.Println(a) // 3
}
// 等价于上面的if语句,外层的{}就是隐藏的代码块
{
a := 3
if a == 3 {
fmt.Println(a) // 3
}
}
// 都不影响包级变量a
fmt.Println(a) // 1
}
笔记地址
github:https://github.com/xianyuyixi...
交流学习
微信号:xianyuyixia
微信公众号:闲渔一下