go语言内存泄漏分析 go语言漏洞( 六 )


前面说到 defer 还有其他的任务, 也就是 defer 中执行的 recover 可以捕获 panic 抛出的异常.
还有 defer 可以在 return 之后修改命名的返回值.
上面2个工作要求 defer 只能在函数退出时来执行.
楼主说的 defer 是类似 Swift2.0 中 defer 的行为, 但是 Swift2.0 中 defer 是没有前面2个特性的.
Go中的defer是以函数作用域作为触发的条件的, 是会导致楼主说的在 for 中执行的错误用法(哪个语言没有坑呢?).
不过 for 中 局部 defer 也是有办法的 (Go中的defer是以函数作用域):
for {
func(){
f, err := os.Open(...)
defer f.Close()
}()
}
在 for 中做一个闭包函数就可以了. 自己不会用不要怪别人没告诉你.
1.10 许多语言内置设施不支持用户定义的类型
for in、make、range、channel、map等都仅支持语言内置类型,不支持用户定义的类型(?) 。用户定义的类型没法支持for in循环,用户不能编写像make、range那样“参数类型和个数”甚至“返回值类型和个数”都可变的函数,不能编写像channel、map那样类似泛型的数据类型 。语言内置的那些东西,处处充斥着斧凿的痕迹 。这体现了语言设计的局限性、封闭性、不完善,可扩展性差,像是新手作品——且不论其设计者和实现者如何权威 。延伸阅读:Go语言是30年前的陈旧设计思想,用户定义的东西几乎都是二等公民(Tikhon Jelvis) 。
说到底, 这个是因为对泛型支持的不完备导致的.
Go语言是没啥NB的特性, 但是Go的特性和工具组合在一起就是好用.
这就是Go语言NB的地方.
1.11 没有泛型支持,常见数据类型接口丑陋
没有泛型的话,List、Set、Tree这些常见的基础性数据类型的接口就只能很丑陋:放进去的对象是一个具体的类型 , 取出来之后成了无类型的interface{}(可以视为所有类型的基础类型),还得强制类型转换之后才能继续使用,令人无语 。Go语言缺少min、max这类函数,求数值绝对值的函数abs只接收/返回双精度小数类型 , 排序接口只能借助sort.Interface无奈的回避了被比较对象的类型,等等等等,都是没有泛型导致的结果 。没有泛型,接口很难优雅起来 。Go开发者没有明确拒绝泛型 , 只是说还没有找到很好的方法实现泛型(能不能学学已经开源的语言呀) 。现实是,Go 1.0已经定型,泛型还没有,那些丑陋的接口为了保持向后兼容必须长期存在着 。
Go有自己的哲学, 如果能有和目前哲学不冲突的泛型实现, 他们是不会反对的.
如果只是简单学学(或者叫抄袭)已经开源的语言的语法, 那是C++的设计风格(或者说C++从来都是这样设计的, 有什么特性就抄什么), 导致了各种脑裂的编程风格.
编译时泛型和运行时泛型可能是无法完全兼容的, 看这个例子:
type AdderT interface {
Add(a, b T) T
}
如何评价Go在百度BFE的应用?首先BFE(baidu front end)这个项目是一个功能类似于nginx的项目go语言内存泄漏分析,并不是大家传统意义上理解的前端(html+css+js) 。之所以称作“frontend”是因为它相对于整个应用是处于最前面直接处理用户的http请求的 。
一开始这个项目是使用c语言写的 , 因为业界大多数http服务器也都是使用c来开发的(如apache、nginx)这段时期称作c-BFE时期 。
但是到后期,这个项目遇到go语言内存泄漏分析了一些问题:
c语言的开发效率太低了
c语言应对需求变更比较吃力
c语言抽象能力不足
c语言需要手动管理内存(有些不很优秀的组员会写出导致内存泄漏的代码)
bug越改越多,稳定性和功能是一对矛盾

推荐阅读