继上篇 Go 问答汇总,已通过去了一个多月。今天汇总下近一个多月我关于 Go 的回答。python
粗略数了一下,一个多月的时间里,大约回答了 18 个与 Go 有关的问题,问题主要是来源于 segmentfault 和 zhihu 两个平台。后面但愿加入更多平台,如 stackoverflow、github 的感兴趣主题。git
最近在写一个小工具,准备用于帮助本身回答不一样平台的问题,同时也便于每月的问题汇总。写的有点慢,但愿月底能够完成。github
正文部分开始。golang
golang中如何将redis取出的map[string]string数据解析到目标struct中?web
主要和反射相关。redis
问题主要是关于 map 中若是存在日期字符格式串,如何解析到 time.Time 类型成员中,而对于结构体而言,reflect.Kind() 返回的只能说明字段类型是 struct,并不能肯定真正的类型,这时能够用 Go 的 switch type 类型查询语法实现。数据库
补充一点,在回答中没有提到的。json
在实现 map 到 struct 的通用方法时,咱们比较容易想到支持基础类型,但对于结构体类型而言,可能性太多,如何更灵活地解决问题?我以为,可经过钩子方式实现,即若是自定义类型须要支持 map 到 struct 的转化,可经过在自定义类型上增长钩子方法实现,好比 UnmarshalMap。如何实现可参考下 encoding/json。segmentfault
固然,这个工做已经有人作了,参考 github 上的包,mitchellh/mapstructure。前面说的 Hook 也是支持的。微信
Go 对错误处理有一套本身的理念。这个问题,我只是简单回答了一下,简单的思路,我定义了用户级别错误和系统级别错误。上篇问答汇总也会相似问题。
个人建议是,发生的 error 是否已经严重影响服务逻辑,若是在预判以内的错误,咱们就应该 return error,记录日志,并不须要人工干预才能恢复,不然建议 panic。
举个例子,在通常状况下,服务启动时,须要进行完善的初始化工做,确认各个组件的运行正常。若是初始化都失败了,那就没有必要继续向下走了,应该 panic 赶忙提示。
问题标题看着挺大,其实题主关心是几个核心常量之间的转化关系。主要是三个时间,分别 unix 时间、wall 时间和 absolute 时间。这里面有个相对重要的转化公式,在须要考虑平润年的时候稍微有点复杂。
很少介绍了,具体本身看回答吧。
其实就两点,一是若是数据结构比较大,建议采用指针,不会发生值拷贝。二是若是须要修改结构的话,必须用指针。固然若是是引用类型,好比 chan、slice、 map,就不用考虑这个问题了。
Golang中的make(T, args)为何返回T而不是*T?
make 针对的是 Go 的引用类型,即 chan、slice 和 map,而 new 针对的指针。引用类型为何 make 不是返回指针呢?这样一说好像和上个问题有点相似了,固然由于引用并不存在值类型的那些问题。
在循环中 append map 到 map slice,map slice 中的数据所有为最后一次 append 的数据
与上一个问题知识点相似,map 是引用类型,即便 slice 经过 append 赋值了多份 map 变量,可是其内部指向是同一个地址。
golang中哪些引用类型的指针在声明时不用加&号,哪些在函数定义的形参和返回值类型中不用*号标注
与前面问题相似,具体看回答。
个人理解,从这里向前数的四个问题,考察知识点基本相似,简单点说,就是 make 和 new 和问题。本质上讲,就是变量内部就是什么的问题。
说实话,我也不明白为何 Go 团队没有像为 string 类型那样为 slice 提供相应的标准库帮助 slice 更方便的操做。但其实,即便没有这样的包, slice 常见的各类增删改查也是能够实现,就是稍微有点 hack。具体如何实现,看看个人问答吧。
首先要说 Go 的等值比较比较的是值,而不是地址。Go 中变量的可比较类型是内置的,基本全部类型均可以进行比较,包括 interface 和 struct。两个变量可比较的提早必须是相同类型。但有一点须要说明的是,interface 是不肯定的类型,全部它不但会比较值,还有比较具体的类型。
回答完这个问题后,我忽然想起前段时间比较两个同类型结构体时还用了反射包中 reflect.DeepEqual 方法,真的是浪费资源啊。
golang 中如何禁止一个导出类型直接构造,必须经过new函数来构造?
其余的 oo 语言实现题主要求是很是简单的,只要定义相应的私有成员属性并经过构造函数控制输入的参数便可。
那么 Go 该如何实现呢?其实也很简单,思路与 oo 是相似的。只是咱们把 oo 语言中的构造函数换成了 Go 中的工厂方法,私有变量变成了 Go 包级别的私有成员属性。咱们只须要经过定义指定的可导出的工厂方法建立实例便可。
我从入门、中级到进阶三个阶段推荐了几本书。有兴趣的朋友,具体查看回答吧。
这个问题的回答,我是先学先买的。看了 medium 中几篇关于 plugin 使用案例的文章,总共花了大概三四小时。plugin 包使 Go 是能够实现动态模块加载的能力,能够在不用从新编译主程序的状况下加入新功能。这是有必定的价值的。
但 plugin 包也存在一些问题,使用起来会用一些限制因素。但若是咱们清楚地了解,仍是能拎的清咱们应该在什么场景下使用它。具体有啥限制,查看回答吧。
这个问题,我并无找到啥好办法,能想到的就是经过加密解密的方式解决。固然,其实在真实的项目中,咱们能够经过引入外部服务实现,好比 k8s 的配置加密功能,使用 ectd 管理配置等。
go语言中, 空的死循环与永远阻塞的chan细节上有什么差别?
Goroutine 是抢占式的,这不一样于传统的协程模型。但它又不是彻底的抢占式,单核的状况下,仍是须要 CPU 主动出入资源的,而空死循环将会一直占用着 CPU,对资源的浪费严重,而 chan 阻塞会出让 CPU 资源,实现并发执行。这应该是二者最大的不一样吧。
除了通常的 chan 实现阻塞,问答还介绍一些其余方式,也能够实现相似的效果。感兴趣的朋友可查看回答。
Golang中fmt.Println和直接println有什么区别?
println 主要是 Go 本身使用,好比源码、标准库等,而 fmt 才是给 Go 开发人员使用的。并且要提的是 println 不能保证兼容性,可能在将来的某一天就不存在了,但 fmt 中的函数就不存在着这样的问题。
固然,二者的使用和效果上也是有区别的,如 println 输出是到标准错误的,而非标准输出。
这个回答是个大工程,零零碎碎花了我差很少三个星期的时间。什么缘由呢?
我提了一个阅读源码的思路,分红了大概三步,大体分别是,了解使用、熟悉架构和剖析原理。我最近在思考是否本身也开始剖析源码,因而决定先以第一步入手,把 Go 的源码整个撸一篇,大概了解涉及了的内容和它们的用途。总共涉及四十多个部分,因而花的时间就比较长。
第一步,了解使用这一块,有些部分达到了解使用,可是有些部分只是达到了解的层次。若是要完整阅读源码,很难,但大概阅读仍是可行的。准备等等合适时机启动系统的源码阅读的计划。
golang数据库操做的时候,须要go func()吗?跟python异步操做yield有什么不一样?
上篇 Go 问答汇总篇 也有相似问题。个人理解,使用 go func 的前提是必须有可并行执行的任务,这是一个重要前提。
不少时候,你们学 Go 都是冲着 Go 的并发来的,结果学以后发现压根用不上,很郁闷啊,总以为哪里用的不对,不该该是这样的。通常的业务开发,特别是 web 的业务开发,使用并发的场景确实很少。而并发性能的问题,服务框架已经帮助咱们实现了,彻底没有插手机会,要想真正学会并发,不能只是天天的增删改查。
汇总完毕!回答若有错误,欢迎你们指正。最后,感谢阅读,汇总篇彷佛是比较枯燥的!