思维导图~
常量
常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,需要把var
换成了const
,常量在定义的时候必须赋值。
go
const pi = 3.14
const e = 2.7182
同样,常量也可以批量声明
go
const (
pi = 3.14
e = 2.7182
)
在使用const声明多个常量时,如果省略初始化值则表示与上一行的常量值相同。
go
const (
a = 1314
b
c
)
func main() {
fmt.Printf("a = %d\n", a)
fmt.Printf("b = %d\n", b)
fmt.Printf("c = %d\n", c)
}
// 执行结果
a = 1314
b = 1314
c = 1314
iota
在 Go 语言中,iota
是一个预定义标识符,它是一个常量计数器,只能在常量的表达式中使用。
iota
表示一个整数值,在const关键字出现时将被重置为0,const中每新增一行常量声明时,iota
计数一次。
iota
可以被用于枚举类型(enum)的定义中,用于简化代码并使得代码更加易读。
使用_
时iota
的变化:
go
const (
a = iota
b
_
c
)
func main() {
fmt.Printf("a = %d\n", a)
fmt.Printf("b = %d\n", b)
fmt.Printf("c = %d\n", c)
}
// 执行结果
a = 0
b = 1
c = 3
iota
声明中插入其他常量声明:
go
const (
a = iota
b
name = "serena"
c = iota
)
const d = iota
func main() {
fmt.Printf("a = %d\n", a)
fmt.Printf("b = %d\n", b)
fmt.Printf("c = %d\n", c)
fmt.Printf("d = %d\n", d)
}
// 执行结果
a = 0
b = 1
c = 3
d = 0
多个iota
定义在一行:
go
const (
a, b = iota + 1, iota + 2 // 1, 2
c, d // 2, 3
e, f // 3, 4
)
变量
Golang语言是静态类型语言,因此Go变量有明确的数据类型,编译器也会检查变量类型的正确性。变量需要声明后才能使用,同一作用域内不支持重复声明。 并且Go语言的变量声明后必须使用。
变量声明
Go变量的标准声明如下:
go
var 变量名 变量类型
例如,声明一个名为name
的变量,该变量的类型为string
:
go
var name string
变量的命名规则遵循驼峰命名法 ,即首个单词小写,每个新单词的首字母大写 ,例如:firstName
另外在变量声明时,可以实现批量声明
go
package main
import "fmt"
var (
a int
b string
c float32
)
func main() {
//%d 整数占位符,%s 字符串占位符, %f 浮点数占位符(默认精度为6)
fmt.Printf("%d, %s, %f", a, b, c)
}
// 执行结果
0, , 0.000000
变量初始化
当一个变量被声明之后,系统自动赋予它该类型的零值: int 为 0
,float 为 0.0
,bool 为 false
,string 为空字符串
,指针为 nil
go
func main() {
var a int
var b float32
var c bool
var d string
var e *struct{}
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
}
// 执行结果
0
0
false
<nil>
类型推导
当声明且初始化变量时,如果没有指明变量类型,则会在编译时自动推导类型。
go
func main() {
var name = "Ming"
fmt.Printf("%T", name)
}
// 执行结果
string
短变量声明
在Go中可以使用简短格式声明并初始化变量 ,同样,Go在编译时会进行自动推导类型
go
变量名 := 值/表达式
name := "value" // name是变量名 "value"可以是值,或者是表达式
使用简短格式声明并初始化变量时,需要注意一下几点
- 简短格式声明变量时,需要同时显示初始化变量;
- 简短格式声明变量时,不能提供数据类型,Go 会根据右侧的值自动推断变量的数据类型;
- 简短格式声明变量只能在函数内使用,不能在函数外使用;
在初始化变量时,不能够重复初始化
go
func main() {
var age int = 10
// 再次声明并赋值 会报错
// No new variables on the left side of ':='(左边的变量已经被声明了,不能重复声明)
age := 20
}
但是有特例,在多个短变量声明和赋值中,至少有一个新声明的变量出现在左值中,即便其他变量名可能是重复声明,编译器也不会报错。
go
package main
import (
"fmt"
"net"
)
func main() {
connOne, err := net.Dial("tcp", "127.0.0.1:8080")
connTwo, err := net.Dial("tcp", "127.0.0.1:8080")
fmt.Println(connOne)
fmt.Println(connTwo)
fmt.Println(err)
}
匿名变量
当使用多重变量赋值时,如果不需要接收特定的返回值,可以使用匿名变量,匿名变量以"_"下划线表示,例如:
go
func main() {
//connOne, err := net.Dial("tcp", "127.0.0.1:8080")
// 如果不想接收err的值,则可以使用匿名变量,_ 表示
connTwo, _ := net.Dial("tcp", "127.0.0.1:8080")
fmt.Println(connTwo)
}
匿名变量的特点在于既不会分配内存,也不会占用命名空间,可以重复声明使用。
变量作用域
Go 变量的作用域是指变量在程序中的可见性和可用性 ,变量的作用域由其声明的位置确定。
在函数内部声明 的变量只在函数内部可用,称为局部变量 或函数作用域变量。
在函数外部声明 的变量称为全局变量 或包作用域变量,在整个包中都可以被访问和使用。
在函数定义中的变量称为形式参数,简称形参。
Go(静态语言)会在编译时检查每个变量是否使用过,一旦出现未使用的变量,则会出现编译报错。
局部变量
在函数体内声明 的变量称为局部变量
。该类型变量的作用域为函数体内,在函数中的参数变量和返回值变量都属于局部变量的范畴。
go
func main() {
var num1 int = 10
var num2 int = 20
sum := num1 + num2
fmt.Printf("num1 = %d, num2 = %d, sum = %d\n", num1, num2, sum)
}
// 执行结果
num1 = 10, num2 = 20, sum = 30
全局变量
在函数体外声明的变量称为全局变量,全局变量只需要在一个源文件中定义,就可以在所有源文件中使用
。
全局变量声明必须以 var 关键字开头
。
go
package main
import "fmt"
// 声明全局变量
var sum int
func main() {
// 声明局部变量
var num1, num2 int
// 初始化参数
num1 = 10
num2 = 20
sum = num1 + num2
fmt.Printf("num1 = %d, num2 = %d, sum = %d", num1, num2, sum)
}
// 执行结果
num1 = 10, num2 = 20, sum = 30
Go语言程序中全局变量与局部变量名称可以相同,但是函数体内的局部变量会被优先考虑。
go
package main
import "fmt"
// 声明全局变量
var name string = "Krito"
func main() {
name := "Asuna"
fmt.Println(name)
}
// 执行结果
Asuna
如果一个 Go 源文件中定义了全局变量,并且其他包外源文件需要使用这个全局变量,那么这些源文件需要使用 import
关键字引入定义这个全局变量的源文件所在的包,并且该全局变量的首字母必须大写
,才能够使用这个全局变量。
go
// util.go
package util
// 声明全局变量,若需要外部包使用,则需要开头字母大写表示包外可见
var Global = "string"
go
// main.go,注意main.go与util.go两个文件在不同的包下
package main
import (
"fmt"
"go-basic/variable/func/util"
)
func main() {
fmt.Println(util.Global)
}
形式参数(形参)
在定义函数时函数后面括号中的变量称为形式参数,简称形参。
形参只会在函数调用时才会生效,函数调用结束后形参就会被销毁,在函数未被调用时,函数的形参并不会占用实际的存储单元且没有实际值。形式参数会作为函数的局部变量来使用
。
go
package main
import "fmt"
// 全局变量 num1
var num1 int = 10
func main() {
// 局部变量 num1 和 num2
var num1 int = 20
var num2 int = 30
fmt.Printf("main() 函数中 num1 = %d\n", num1)
fmt.Printf("main() 函数中 num2 = %d\n", num2)
sum := sum(num1, num2)
fmt.Printf("main() 函数中 sum = %d\n", sum)
}
func sum(num1, num2 int) int {
fmt.Printf("sum() 函数中 num1 = %d\n", num1)
fmt.Printf("sum() 函数中 num2 = %d\n", num2)
cal := num1 + num2
return cal
}
// 执行结果
main() 函数中 num1 = 20
main() 函数中 num2 = 30
sum() 函数中 num1 = 20
sum() 函数中 num2 = 30
main() 函数中 sum = 50
变量生命周期
在Go语言中,变量的生命周期由变量的作用域
和垃圾回收机制
共同决定。
当一个变量超出其作用域时,将被自动释放。而垃圾回收机制负责回收不再使用的内存。
在Go语言中,所有变量的内存都是在堆上分配的 ,垃圾回收器会定期检查堆上的变量,回收那些不再使用的内存。
因此,Go语言具有自动内存管理的特点,程序员不需要手动进行内存分配和释放操作。
全局变量
是定义在函数外部 的变量,具有全局可见性和生命周期,程序在整个执行期间都可以访问这些变量。
局部变量
是定义在函数内部 的变量,具有局部可见性和生命周期,变量在函数执行完成后就会被销毁。
在使用变量时,需要考虑它们的作用域和生命周期,合理地选择变量的存储位置和释放时机,从而提高程序的性能和稳定性。