00 环境
参考的:https://www.liwenzhou.com/posts/Go/install/
编译运行:
go mod init <项目名> // 在目录下创建项目
go build <项目名> // 编译
go build -o <项目名>.exe // 编译
go run <文件名>.go //快速运行
go windows编译linux可执行文件
在cmd或者powershell执行以下命令
set GOARCH=amd64
go env -w GOARCH=amd64
set GOOS=linux
go env -w GOOS=linux
再切换回windows
go env -w GOARCH=amd64
go env -w GOOS=windows
在Linux上的可执行文件需要设置权限:
chmod +x 可执行文件名
从windows向linux服务器的可执行文件传输
在本地 Windows 系统上:
使用 certutil 命令进行编码: Windows 上的 certutil 工具可以用来将文件编码为 Base64 格式。
certutil -encode your_executable encoded_file.txt
然后注意将Base64的文本文件内容中的头尾去掉
解码文件并还原为可执行文件: 在远程服务器上,在Linux下新建文件并复制以上文件的内容,使用 base64 命令将文本文件解码为二进制格式,并将其还原为可执行文件。
base64 -d encoded_file.txt > your_executable
01 语言基础
匿名变量用一个下划线_表示,不占用命名空间,不会分配内存
数组是值类型,赋值和传参会复制整个数组。因此改变副本的值,不会改变本身的值。
[n]T表示指针数组,[n]T表示数组指针 。
切片每次扩容后都是扩容前的2倍。
在Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储。而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。
make也是用于内存分配的,区别于new,它只用于slice、map以及channel的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。
使用&对结构体进行取地址操作相当于对该结构体类型进行了一次new实例化操作。
p3 := &person{}
fmt.Printf("%T\n", p3) //*main.person
fmt.Printf("p3=%#v\n", p3) //p3=&main.person{name:"", city:"", age:0}
p3.name = "七米"
p3.age = 30
p3.city = "成都"
fmt.Printf("p3=%#v\n", p3) //p3=&main.person{name:"七米", city:"成都", age:30}
p3.name = "七米"其实在底层是(*p3).name = “七米”,这是Go语言帮我们实现的语法糖。
结构体占用一块连续的内存。
问题:
type student struct {
name string
age int
}
func main() {
m := make(map[string]*student)
stus := []student{
{name: "小王子", age: 18},
{name: "娜扎", age: 23},
{name: "大王八", age: 9000},
}
for _, stu := range stus {
m[stu.name] = &stu
}
for k, v := range m {
fmt.Println(k, "=>", v.name) // 娜扎 => 大王八
} // 大王八 => 大王八
} // 小王子 => 大王八
chatGPT的解释:
在 Go 语言中,range 循环中的迭代变量 stu 是对切片中每个元素的拷贝,而不是直接引用切片中的元素。因此,虽然 stu 的值在循环迭代中会改变,但它实际上是对切片中相应元素的一个副本。
在循环迭代中,stu 每次都会被重新赋值为切片中的下一个元素,而不是引用切片中元素的地址。因此,&stu 取的地址是固定的,但指向的内存地址会随着 stu 的重新赋值而改变。
当访问结构体成员时会先在结构体中查找该字段,找不到再去嵌套的匿名字段中查找。
GO通过嵌套匿名结构体实现继承
recover是一个用于恢复程序执行的函数。当panic发生时,Go语言运行时会查找调用栈中的defer函数,并检查是否存在recover函数。如果存在,程序将停止继续向上传播panic,并开始执行recover函数。
panic 只会触发当前 goroutine 中的 defer 操作