go理论知识记录(入门)
go理论知识记录(入门)
ps:来源于刘丹冰老师的课程
Go 语言中的变量定义
1. 使用 var
关键字定义变量
语法:
var 变量名 类型 = 值
- 如果未初始化,变量会被赋予其类型的零值:
var score int // 默认值为 0 var isPass bool // 默认值为 false var greeting string // 默认值为 ""
2. 类型推断(省略类型)
Go 支持类型推断,可以根据初始值自动推断变量类型。
语法:
var 变量名 = 值
3. 短变量声明(:=
)
在函数内部,可以使用短变量声明(:=
)来定义变量,省略 var
关键字和类型。
语法:
变量名 := 值
- 注意:短变量声明只能在函数内部使用。
4. 同时定义多个变量
可以一次性定义多个变量,用逗号分隔。
语法:
var 变量1, 变量2, 变量3 = 值1, 值2, 值3
5. 定义常量
使用 const
关键字定义常量,常量的值在程序运行期间不可修改。
语法:
const 常量名 = 值
6. 变量的作用域
- 局部变量:在函数内部定义的变量,只能在该函数内部访问。
- 全局变量:在函数外部定义的变量,可以在整个包内访问。
示例:
package main
import "fmt"
var globalVar = "I am global" // 全局变量
func main() {
localVar := "I am local" // 局部变量
fmt.Println(globalVar) // 可以访问全局变量
fmt.Println(localVar) // 可以访问局部变量
}
7. 匿名变量(_
)
使用 _
作为变量名,表示忽略该值。
示例:
func getData() (int, string) {
return 10, "hello"
}
func main() {
num, _ := getData() // 忽略第二个返回值
fmt.Println(num)
}
关于导包的三种方式
pkg的包的最底层的init函数是最先执行的
- 匿名
- 起别名
- 全部导入
- 如果包导入之后不使用是会报错的 > 补救:在不直接用的包前面加上_表示是匿名导入 ```go import ( _ "goLearningDemo/init/lib1" "goLearningDemo/init/lib2" ) ```
- 可以给包起别名
import (
_ "goLearningDemo/init/lib1"
myLib2 "goLearningDemo/init/lib2"
)
- 如果是用.导包的话,视作是将包内所有的文件全都导入到目前的文件下面,那么当前文件内可以不用连着报名调用函数,而是直接调用
尽量不用轻易使用
import (
_ "goLearningDemo/init/lib1"
. "goLearningDemo/init/lib2"
)
指针
package main
import "fmt"
func swap(a * int,b *int){
var tmp int
tmp = *a
*a = *b
*b = tmp
}
func main(){
a:=100
b:=200
swap(&a,&b)
fmt.Println("a = ",a)
fmt.Println("b = ",b)
}
defer关键字
- 谁最先提出谁最后执行
- 如果defer和return都存在的情况,那么也是return先执行
package main
import "fmt"
func main () {
defer fmt.Println("close1.....")
defer fmt.Println("close2.....")
fmt.Println("hello1")
fmt.Println("hello2")
}
结果
hello1
hello2
close2…
close1…
切片 => 数组 (不初始化默认是0)
静态数组
- 创建空数组,且大小固定
var myarr1 [10] int
遍历方式:
//第一种
for i := 0; i < len(myarr1); i++ {
fmt.Println(myarr1[i])
}
//第二种
for index,value:=range myarr1{
fmt.Println("indexa:",index,",value = ",value)
}
- 创建大小固定的数组,初始化了前几个
myarr1:= [10] int{1,2,3,4}
- 查看数组的类型
fmt.Printf("%T\n",myarr1)
//res:[10]int
动态数组
package main
import "fmt"
//数组的长度是不固定的
//动态数组传参时候是引用传递的,方便在内部进行修改
func printArray(myarr []int) {
//不需要index的时候可以用小下划线代替
for _ , value := range myarr{
value = value - 1
fmt.Println("value = ",value)
}
}
func main () {
myarr2 := [] int {1,2,3,4}
fmt.Printf("%T\n",myarr2)
printArray(myarr2)
}
数组相关的api操作
追加元素
//容量是5,但是目前只有三个元素(长度是3)
var numbers = make([]int, 3,5)
fmt.Printf("slice = %v\n",numbers)
//追加元素1(当前长度是4)
numbers = append(numbers,1)
fmt.Printf("slice = %v\n",numbers)
追加元素
cap(numbers)
- 如果在追加的时候,空间不够的话,go会给你再开辟一个新的大小为之前cap的容量
即每次扩容是翻倍
截取
//切片
s1 := numbers[0:2]
fmt.Printf("s1 = %v\n",s1)
- 切片的截取是左闭右开的[0,2)
- 注意:这里的是浅拷贝,go是有copy函数去完成深拷贝的
s1 := numbers[0:2]
fmt.Printf("s1 = %v\n",s1)
//深拷贝
s2 := make([]int, 3)
copy(s2,s1)
fmt.Printf("s2 = %v\n",s2)
map
map的声明(三种)
- 第一种方式
//声明map(当前是空值)
var myMap map[string]string
//使用之前要先开辟空间
myMap = make(map[string]string, 10)
myMap["one"] = "java";
myMap["two"] = "python";
myMap["three"] = "C++";
- 第二种方式(可以省略容量,直接开辟空间)
myMap2 := make(map[string]string)
myMap2["one"] = "java";
myMap2["two"] = "python";
myMap2["three"] = "C++";
fmt.Println(myMap2)
- 第三种方式,顺便初始化 !不需要开辟空间!
myMap3 := map[string]string {
"one":"java",
"two":"python",
"three":"C++",
}
fmt.Println(myMap3)
#### 基本操作
###### 1. 创建 Map
使用 `make` 函数创建一个 `map`:
```go
cityMap := make(map[string]string)
2. 添加键值对
通过指定键来添加值:
cityMap["one"] = "beijing"
cityMap["two"] = "shanghai"
cityMap["three"] = "hefei"
3. 遍历 Map
使用 for range
循环遍历 map
:
fmt.Println("遍历======")
for key, value := range cityMap {
fmt.Println("key = ", key)
fmt.Println("value = ", value)
}
4. 删除键值对
使用 delete
函数删除指定键的键值对:
fmt.Println("删除======")
delete(cityMap, "one")
for key, value := range cityMap {
fmt.Println("key = ", key)
fmt.Println("value = ", value)
}
5. 修改键值对
通过指定键来修改值:
fmt.Println("修改======")
cityMap["two"] = "wuhan"
for key, value := range cityMap {
fmt.Println("key = ", key)
fmt.Println("value = ", value)
}
完整代码
package main
import "fmt"
func main() {
// 创建 map
cityMap := make(map[string]string)
// 添加键值对
cityMap["one"] = "beijing"
cityMap["two"] = "shanghai"
cityMap["three"] = "hefei"
// 遍历 map
fmt.Println("遍历======")
for key, value := range cityMap {
fmt.Println("key = ", key)
fmt.Println("value = ", value)
}
// 删除键值对
fmt.Println("删除======")
delete(cityMap, "one")
for key, value := range cityMap {
fmt.Println("key = ", key)
fmt.Println("value = ", value)
}
// 修改键值对
fmt.Println("修改======")
cityMap["two"] = "wuhan"
for key, value := range cityMap {
fmt.Println("key = ", key)
fmt.Println("value = ", value)
}
}
输出结果
遍历======
key = one
value = beijing
key = two
value = shanghai
key = three
value = hefei
删除======
key = two
value = shanghai
key = three
value = hefei
修改======
key = two
value = wuhan
key = three
value = hefei
注意
- 键的唯一性:
map
中的键是唯一的,如果重复添加相同的键,后添加的值会覆盖之前的值。 - 并发安全:
map
不是并发安全的。如果需要在并发环境中使用map
,需要使用同步机制(如sync.Map
或mutex
)。