变量的本质是计算机分配的一块内存,用于存放数据,变量是在程序运行过程中,其值可以发生改变的数据,变量属于临时存储,当程序运行结束,存放该数据的内存就会释放,该变量就会随着内存的释放而消失。
因为内存分配发生在运行期,所以在编码阶段我们用一个易于阅读的名字来表示这段内存,称为变量名。 而变量名只是为了让我们开发者更好的查找和使用,实际上编译后的机器码从不使用变量名,而是通过内存地址来访问目标数据。
声明变量后就可以用=为它分配该类型的任何值
变量名首字母大小写决定了其作用域,首字母大写相当于公开,可以被包外引用,而小写相当于私有,仅能在包内使用。(fmt.Println中的P是大写的,这样它就可以在任意包下被调用)
命名规则:
var c int // c代替count
for i := 0; i < 10; i++ { // i代替index
c++
}
仅定义变量未初始化时,变量根据数据类型赋上默认值
整型、浮点型默认值 = 0
字符串默认值 = ""
布尔型默认值 = false
函数、指针变量、切片默认值 = nil
格式:
var 变量名 数据类型 // 仅定义,未赋值
var 变量名 数据类型 = 变量值 // 定义并赋值
演示:
func main() {
var x int // 定义x 没初始化 默认值0
var y = 1 // 定义y 有初始化 数据类型int 将1赋值给y
var z bool // 定义z 没初始化 默认值为false
var a int // 先定义a
a = 1 // 然后把1再赋值给a
fmt.Println(x, y, z, a)
}
可以一次性定义多个变量
var 变量1,变量2 = 变量1值,变量2值
演示:
func main() {
var x, y int // 多个变量相同数据类型
var n, m = 100, "itzhuzhu" // 多个变量不同数据类型
fmt.Println(x, y, n, m)
}
多个变量以组的方式定义,不再需要每行都写var
func main() {
var (
x, y int // 多个变量相同数据类型
n, m = 100, "itzhuzhu" // 多个变量不同数据类型
)
fmt.Println(x, y, n, m)
}
变量存储:
等号左边代表变量的内存空间(写)
等号右边代表内存空间存储的数据值(读)
在给变量赋值时,可以简化书写,使用:
代替var由编译器根据赋值数据推断数据类型。
func main() {
w := 1
x, y, z := 2.3, 4, "itzhuzhu"
fmt.Println(w, x, y, z)
var intVal int
intVal =1
}
拆分:=,:=做了两步的工作,所以声明的时候使用:=,再次赋值的时候使用=
name := "娜可露露"
// 相当于
var name string
name = "娜可露露"
自动推导类型的弊端:
局部变量
,只能在同一个作用域下被调用var x = 1 // 定义全局变量
func main() {
fmt.Println(&x, x) // 全局变量
var x = "局部变量" // 局部变量
fmt.Println(&x, x)
}
输出:
0x10425c288 1
0x14000010070 局部变量
自动推导类型前提是至少有一个新声明的变量出现在左侧且在同一个作用域,即使其他变量名是重复的,编译器也不会报错
func main() {
x := 1
fmt.Println(&x)
x, y := 2, "abc" // x在这里是重新赋值 y是定义新变量
fmt.Println(&x, x, y)
}
打印结果:
0x14000096f60
0x14000096f60 2 abc
没有新的变量
func main() {
x := 1
fmt.Println(&x)
x := 2 // 报错:':=' 的左侧没有新变量
fmt.Println(&x, x)
}
有新的变量但不在同一个作用域将作为新变量定义
func main() {
x := 1
fmt.Println(&x)
{
x, y := 1, 2 // 这里的x和上面的x已经是不同作用域了,x,y全部视为定义新变量
fmt.Println(&x, x, y)
}
}
输出:
0x14000064f60
0x14000064f58 1 2
在进行多变量赋值操作时,首先计算出所有右值,然后依次完成赋值操作,但必须保证左右值的数据类型相同
func main() {
x, y := 1, 2 // x:1 y:2
x, y = y+3, x+2 // 先计算出右值y+3、x+2,然后再把结果赋值给左边的x、y变量
fmt.Println(y)
}
变量值交换:
func main() {
var a = 1
var b = 2
var c int // 定义第3个变量
c = a // 把a的值给c
a = b // 把b的值给a
b = c // 把c的值给b
fmt.Println(a, b)
}
// 也可以使用自动推导类型赋值的方式交换变量值
func main() {
var a = 1
var b = 2
a, b = b, a
fmt.Println(a, b)
}
通常定义变量后未使用编译器就会报错,使用_
可用来临时规避编译器对未使用变量和导入包的错误检查,匿名变量既不占用命名空间,也不会分配内存。
import (
"fmt"
_"os" // 对于还没用到且不想删除的可以加上占位符,避免编译报错
)
_, err = conn.Write([]byte(fileName)) // _:表示忽略占位符
if err != nil {
fmt.Println("conn.Write err:", err)
return
}