2024-12-11 GO语言资料收集

0.  GO语言值和指针的区别在于函数传值还是传引用

1.  《理解GO协程调度的本质》

一篇发在腾讯技术工程公众号上的文章,很少见的把GO协程讲的这么明白的了。

2. 《100 个 Go 语言典型错误》

(法)Teiva Harsanyi(泰瓦·哈尔萨尼) 著

了解一门语言的缺点,换一个角度看问题,可以更加深入的理解一门语言。

抱着这个想法我在知乎上找到了这本电子书 电子书

问题一: := 写起来太容易。

:= 和var一起用很容易导致变量隐藏问题。下面这个例子,外层的client始终是nil

问题二:不必要的嵌套。

        我认为这个问题并不是GO独有的问题,但是这的确是一个优化的角度,即选择合适的Guardian Clause可以优化代码、提高可读性。

问题三:滥用 init 函数。

首先,init函数是什么?

init是用于初始化应用程序状态的函数,在初始化包的时候执行。

init函数不能被主动调用。

init缺点:

        1. 不要依赖一个包内的多个文件中init函数的执行顺序(按照源文本首字母顺序)

        2. init函数不能返回错误,只能panic,这可能是无法接受的。

        3. init函数没有参数,因为如果要传参数,则需要使用全局变量。使用全局变量是一件很危险的事。

        4. 如果要在这个文件中写测试代码,那么init函数会在测试代码之前运行。

我的思考:

        应该严格限制init函数的用处,究竟有什么内容是适合写在init函数中的?

显然,问题就出在这句在初始化包时执行。如果是多个包呢?

  • 比如main依赖redis,那么顺序为:redis的init -> main的init -> main剩余代码。
  • 一个包内可能有多个init,比如 a.go和b.go都有init,那么会按照源文件的字母顺序执行: a的init -> b.init
  • 甚至可以在一个文件定义多个init函数(真的不推荐这么做),看这个例子

  • 你可能也见过一些在 import代码块中直接重命名为 `_` 的代码块,实际上这么做就是为了运行包中的init函数。main包 import _ "foo",意义为 在main之前运行 foo的init函数

问题四:GO不强制使用Getter和Setter.

完全不使用Getter/Setter或者过度滥用Getter/Setter都可能造成问题。

以time标准库为例:它让你直接访问public的成员来完成Getter和Setter。

当然,你可以全都设置为私有成员,例如:time.c,然后通过提供public的getter/setter函数。

type myData struct {
    var balance int
}

func (m *myData) Balance() int {
    return s.balance
}

func (m *myData) SetBalance(new value) {
    s.balance = value
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值