欢迎来到张胤尘的技术站
技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌
变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。
golang
语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。
变量是存储数据的容器,其值在程序的运行过程中是可以被修改。由于 golang
是强类型语言,所以在变量声明时需要指定类型,但也可以通过编译器的自动类型推断来省略显式类型声明
var
关键字声明变量var a int = 10
var b string = "Hello"
这里 var
关键字用于声明变量,a
和 b
分别是变量名,int
和 string
是变量类型,10
和 "Hello"
是变量的初始值。
var a = 10
var b = "Hello"
如果变量在声明时直接赋值,golang
语言会根据赋值的内容自动推断变量的类型。
a := 10
b := "Hello"
在函数内部,可以使用 :=
来声明并初始化变量。但是这种方式只能在函数内部使用,且变量的类型会根据赋值的内容自动推断。
另外在使用短变量声明时需要注意的是,出现在 :=
左侧的变量不应该是已经被声明过的,否则会导致编译错误
golang
中支持一次性声明多个变量,语法如下所示:
// 类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
// 自动推断
var vname1, vname2, vname3 = v1, v2, v3
// 短变量声明,自动推断
vname1, vname2, vname3 := v1, v2, v3
// 这种因式分解关键字的写法一般用于声明全局变量
var (
vname1 v_type1
vname2 v_type2
)
变量在声明时可以初始化,也可以不初始化。未初始化的变量会自动赋予其类型的零值(如 int
的零值是0,string
的零值是空字符串""),具体如下表格所示:
类型 | 零值 |
---|---|
int 、int8 、int16 、int32 、int64 |
0 |
uint 、uint8 、uint16 、uint32 、uint64 、uintptr |
0 |
float32 、float64 |
0.0 |
complex64 、complex128 |
0 + 0i |
bool |
false |
string |
"" (空字符串) |
[n]T (数组) |
每个元素初始化为其类型的零值 |
[]T (切片) |
nil |
map[K]V (字典) |
nil |
struct (结构体) |
每个字段初始化为其类型的零值 |
*T (指针) |
nil |
chan T (通道) |
nil |
interface{} (接口) |
nil |
[3]int
的零值是 [0 0 0]
。type Person struct {
Name string
Age int
}
Person
的零值是 {Name: "", Age: 0}
。
nil
,表示它们没有指向任何有效的内存地址或值。全局变量是在函数外部定义的变量,它们在整个程序中都是可见的。全局变量在程序开始执行时分配内存,直到程序结束时才释放。
package main
import "fmt"
var g int = 10
func main() {
// 输出全局变量的值 10
fmt.Println(g)
}
局部变量是在函数内部或代码块(如 if
、for
、switch
等语句)中声明的变量。它们的作用域仅限于声明它们的函数或代码块内部。
package main
import "fmt"
func main() {
x := 10 // 局部变量,作用域为main函数
{
y := 20 // 局部变量,作用域为这个代码块
fmt.Println(y) // 可以访问
}
// fmt.Println(y) // 错误:y的作用域已结束
fmt.Println(x) // 可以访问
}
当程序执行到局部变量的声明语句时(如 var x int
或 x := 10
),golang
运行时会为该变量分配内存。内存分配的具体位置(栈或堆)取决于变量的类型和使用方式。
通常分配在栈上的变量:
int
、float64
、string
等)通常会被分配在栈上。func myFunction() {
x := 10 // 局部变量,分配在栈上
y := "Hello" // 局部变量,分配在栈上
z := [3]int{1, 2, 3} // 数组,分配在栈上
}
通常分配在堆上的变量:
[]T
):切片本身是一个引用类型,它包含一个指向底层数组的指针、长度和容量。底层数组通常会被分配在堆上。map[K]V
):字典是一个复杂的数据结构,其内部实现使用了动态分配的内存,通常会被分配在堆上。struct
):如果结构体的大小较大,或者结构体被分配到一个更大的数据结构中(如切片或字典),那么结构体可能会被分配在堆上。*T
):指针本身是一个简单的类型,通常分配在栈上,但指针指向的对象可能会被分配在堆上。interface{}
):接口是一个引用类型,其内部实现使用了动态分配的内存,通常会被分配在堆上。func myFunction() {
var x *int = new(int) // 指针,指向的值分配在堆上
y := []int{1, 2, 3} // 切片,底层数组分配在堆上
z := make(map[string]int) // 字典,分配在堆上
}
需要额外说明的是,golang
编译器也会根据变量的使用方式和生命周期来决定内存分配的位置。即使是一个简单的类型(如 int
),如果它的生命周期超出了函数调用范围,或者需要动态分配,它也可能会被分配在堆上。
func myFunction() *int {
x := 10 // 局部变量,但返回了它的地址
return &x
}
在这个例子中,x
的生命周期超出了函数调用范围(因为返回了它的地址),因此编译器会将 x
分配在堆上,以确保返回的指针仍然有效。
常量是一个简单值的标识符,在程序运行时,不会被修改的量。需要注意的是常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
常量的定义格式如下所示:
const identifier [type] = value
const
关键字声明const pi float64 = 3.14159
const max int = 100
这里 const
关键字用于声明常量,pi
和 max
分别是常量名,float64
和 int
是常量类型,3.14159
和 100
是常量的值。
const pi = 3.14159
const max = 100
如果常量在声明时直接赋值,golang
语言会根据赋值的内容自动推断常量的类型。
const c_name1, c_name2 = value1, value2
全局常量可以采用如下的形式进行多个常量的声明:
const (
globalConst1 int = 100
globalConst2 string = "Hello, World!"
)
全局常量是在函数外部声明的常量,它们的作用域是整个包(package
)。全局常量可以在包内的任何地方访问,包括所有函数和代码块。
局部常量是在函数内部或代码块中声明的常量,它们的作用域仅限于声明它们的函数或代码块。
package main
import "fmt"
// 全局变量
var globalVar int = 100
// 全局常量
const globalConst int = 200
func main() {
// 局部变量
var localVar int = 50
fmt.Println("局部变量 localVar:", localVar)
// 使用短变量声明
localVar2 := 60
fmt.Println("局部变量 localVar2:", localVar2)
// 局部常量
const localConst int = 300
fmt.Println("局部常量 localConst:", localConst)
// 访问全局变量和全局常量
fmt.Println("全局变量 globalVar:", globalVar)
fmt.Println("全局常量 globalConst:", globalConst)
}
撒花!
如果本文对你有帮助,就点关注或者留个
如果您有任何技术问题或者需要更多其他的内容,请随时向我提问。