作者:matrix
发布时间:2023-06-24
分类:Golang
熟悉面向对象语言的话,Golang的struct结构体有点像面向对象编程中的类
。但这两者不是完全一样,只能说都有继承、封装、多态的特点。
结构体(struct)
结构体可以将零个或多个任意类型的值聚合在一起,能描述多个数据类型
type Person struct {
name string
age int
value string
address string
}
成员方法和接收者
func (p *Person) setName(name string) {
p.name = name
}
说明:
setName
为声明的方法
p *Person
为接收者(指针类型)
struc类型新增成员方法的语法很另类,像是单独给struct做绑定,绑定的时候会有接收者
来指定当前实例类型。
GOlang其实可以给任何类型创建成员方法:
type MyInt int
func (i MyInt) IsZero() bool{
return i == 0
}
这里通过声明int的自定义类型MyInt,然后绑定一个成员方法。灵活~
值接收者 指针接收者
方法的接收者
可以是结构体的值
或者指针
。上面例子的接收者是一个Person类型的指针。指针接收者的一个优点是可以直接修改接收者的字段值,还避免值的拷贝(内部实际上是拷贝的指针)。
声明为值接收者也是可以:
func (p Person) getName() string {
return p.name
}
getName方法会在调用时复制接收者,就可能会导致性能问题。一般是建议使用指针作为接收者
小结
值接收者或者指针接收者 都能调用结构体或者内嵌结构体的方法或者属性。
给结构体绑定成员方法时,参数最好使用指针,防止值拷贝
func (this *Person) setName(name string)
// 申明结构体struct
type Person struct {
name string
age int
value string
address string
}
//结构绑定
// 给结构体绑定成员方法。 不推荐使用,内存利用低效(参数会使用值传递,会内存拷贝)
//p Person这里p表示值接收者
// func (p Person) getName() string {
// 这里的p变量指针和外部调用的mPerson不同,这里属于值拷贝!!!
// return p.name
// }
// 给Person结构体指针绑定成员方法,同上面效果。但是参数属于引用传递
//this为指针接收者
func (this *Person) getName() string {
return this.name
}
// 给Person结构体指针绑定方法
func (this *Person) setName(name string) {
this.name = name
}
func main() {
//创建实例
// var mPerson *Person = new(Person)//返回实例指针
// var mPerson Person = *new(Person)//返回实例
// var mPerson Person = Person{}//返回实例
var mPerson *Person = &Person{name: "Hi~"} //获取实例指针
mPerson.setName("")
fmt.Println(mPerson.getName())
}
作者:matrix
发布时间:2023-02-10
分类:Golang
Golang支持跨平台编译,比起python只能编译为当前平台的二进制文件要好太多。
go build help
$ go help build
usage: go build [-o output] [build flags] [packages]
...
默认编译(输出当前平台二进制文件)
$ go build -ldflags="-s -w" main.go && upx -9 ./main
说明:
upx 该工具用于压缩二进制文件 -9 表示最高压缩率(选择范围为1-9)
跨平台编译
Mac/Linux系统下:
输出Linux可执行文件:
$ CGO_ENABLE=0 GOOS=linux GOARCH=amd64 go build -ldflags='-s -w -extldflags "-static -fpic"' -o main-linux-amd64 main.go && upx -9 ./main-linux-amd64
输出Windows可执行文件:
$ CGO_ENABLE=0 GOOS=windows GOARCH=amd64 go build -ldflags='-s -w -extldflags "-static -fpic"' -o main-windows-amd64.exe main.go && upx -9 ./main-windows-amd64.exe
输出Mac可执行文件:
# Intel
$ CGO_ENABLE=0 GOOS=darwin GOARCH=amd64 go build -ldflags='-s -w -extldflags "-static -fpic"' -o main-darwin-amd64 main.go && upx -9 ./main-darwin-amd64
# Apple Silicon (M1)
$ CGO_ENABLE=0 GOOS=darwin GOARCH=arm64 go build -ldflags='-s -w -extldflags "-static -fpic"' -o main-darwin-arm64 main.go && upx -9 ./main-darwin-arm64
windows系统下:
SET CGO_ENABLE=0
SET GOOS=linux
SET GOARCH=amd64
go build -ldflags='-s -w -extldflags "-static -fpic"' main.go
参数说明
CGO_ENABLE 是否开启CGO。默认为1开启CGO(不支持交叉编译),0表示关闭CGO
GOARCH 表示CPU架构amd64(x86-64 普通家用电脑)、ARM
GOOS 表示操作系统Linux、Windows、Darwin(Mac)
-o 表示输出指定文件名(默认为main)
-a 表示强制重新构建
-ldflags参数
`-s -w` 表示减小体积,去除编译携带的符号表和调试信息
-s 忽略符号表和调试信息
-w 忽略DWARFv3调试信息,将无法使用gdb进行调试
-extldflags "-static -fpic" 表示完全静态编译(默认是静态链接 个别库可能会导致动态链接),这样编译生成的文件就可以任意放到指定平台下运行,不需要运行环境的基础依赖库()
二进制压缩工具upx(可选)
Mac下使用brew安装
$ brew install upx
$ upx --version
upx 3.96
其他平台:
https://github.com/upx/upx/releases
upx压缩工具能省掉40%-70%的大小
-rwxr-xr-x 1 hhtjim staff 7.9M Feb 9 00:13 main-default
-rwxr-xr-x 1 hhtjim staff 5.5M Feb 9 00:15 main-ldflags
-rwxr-xr-x 1 hhtjim staff 2.3M Feb 9 00:34 main-upx
参考:
https://mp.weixin.qq.com/s/hx9Vbdes6cmRNMiUNqOTCQ
https://mp.weixin.qq.com/s/s6QzFkT1YU3lwkuZSHNb-A
https://dev.to/tidalcloud/how-to-cross-compile-go-app-for-apple-silicon-m1-27l6
https://docs.studyGolang.com/pkg/runtime/internal/sys/#pkg-constants
https://zhuanlan.zhihu.com/p/338891206
完全静态编译一个Go程序
https://colobu.com/2018/07/20/totally-static-Go-builds/
Go编译常用参数
https://juejin.cn/post/7096772208999006244
作者:matrix
发布时间:2023-01-31
分类:Golang
变量声明
Golang属于强类型语言,且定义的变量一定要被使用不然会编译报错。
Golang可以使用:=
的语法糖来自动实现类型推断,一般都在非全局变量中使用。var
的声明多用在全局变量声明。
变量赋值后必须使用,否则编译失败
例外: _变量
表示占位变量。不能赋值和调用,仅为占位作用。
var a int = 16
var a = 16 //类型自动推断
//等同于短变量声明
a := 16
//多变量快捷声明
var a, b int
var a, b, c = 16, true, "str" //可以不同类型
变量作用域
{
var b string = "hi~"
fmt.Println("asd")
fmt.Println("b->", b)
}
num := 12
{
a, num := false, 5 // 这里的num会被认为是一个新变量
b := 100
fmt.Println(a, num, b)
}
fmt.Println(a, num) // a: undefined
{ ... }
代码块会限制变量作用域
变量默认值
基本数据类型默认值都是 0、空字符串这些,声明时就划分内存空间
//声明即初始化(划分内存空间)
var a int //0
//等同于 var a int = 0
var a string //""
var a bool //false
var a rune //0
var a byte //0
var a float32 //0
...
其他类型都默认为nil值
var a error
// var a error = nil
var a *int
var a []int
var a map[string]string
...
参考:
https://mp.weixin.qq.com/s/m8iQdGu7g_8PX4s9mFbkDQ
- 1
- 2