3

Effective Go 阅读笔记

 3 years ago
source link: https://liqiang.io/post/note-for-effective-go?lang=ZH_CN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

All Posts

Effective Go 阅读笔记

@POST· 2021-07-24 22:08 · 16 min read

Effective Go

  • 代码一致用 gofmt 格式化,这样就保持风格一致
  • 注释文档
    • 每个 package 都应该有文档,简单的包文档也可以很简单,一两行足以
    • 第一行概要介绍包的作用
    • 如果是一堆常量定义(例如 Error),注释可以一笔带过(liqiang 注:这个有点流于形式了?)
  • package
    • package 名称应该简短,就一个小写单词即可,不应该带下划线(_)以及 mixedCaps 格式
    • 命名无需过长:Long names don’t automatically make things more readable. A helpful doc comment can often be more valuable than an extra long name.
      • eg:once.Do(setup) better than once.DoOrWaitUntilDone(setup)
  • 条件语句
    • 如果 if 的条件流程里面最后会 return,那么 else 关键词就不应该出现,他是多余的,直接在 if 段后面接上就可以了
    • := 如果左边的变量在前面已经定义过了,合不合理看情况:
      • 如果左边的变量全都在之前定义过了,那么会报错
      • 如果左边的变量部分定义过了,部分没定义,那么是合法的,并且,定义过的变量不会重新定义一遍,而是对之前的变量重新赋值
    • for
      • 如果你只需要 slice 的下标 或者 map 的 key,那么你只需要进行: for key := range var
      • 如果只需要值,那就需要忽略前一部分了:for _, v := range var
      • 边遍历 map 的 key,边删除 key 是合法的
      • for 遍历 string 的单位是 rune,所以中文也是可以正确处理的
    • switch
      • Go 的 switch 可以带表达式,也可以不带表达式
      • 不带表达式时,从上到下遍历 case,如果 case 值为 true,执行对应的语句
      • case 支持逗号分隔的多个匹配值
  • defer 如果调用的是一个函数 / 方法,那么值是在调用 defer 的时候先计算好的,而不是在运行函数内容的时候再计算
  • new 只是创建了一个空白的结构,并没有初始化内存,对于一些结构体来说,空白是有意义的,例如 Mutex,空白表示未加锁,所以可以直接使用;
  • make 只能用于 Array/Slice/Map,它是初始化了内存的,例如初始化了数组的长度是 100
  • 数组
    • Go 的数组是传值的,赋值 / 传参一个 Array 不是传的指针,是会对数组的值进行拷贝
    • 数组的 size 也是类型的一部分,[10] int 和 [20] int 是不同的两个类型,不能直接赋值
    • 数组有个比 slice 好的地方在于他的内存是固定的,所以在多重数组的情况下,可以直接使用 array [1][2]
  • map 和 slice 都是传指针的,可以修改内容
  • 如果 map 取值,key 不存在,那么返回的是 value 的零值
  • delete 删除不存在的 map key 是合法的
  • 常量只能是 数字、多个字符(runes)、字符串和 bool 类型
  • 常量是在编译时初始化的,包括函数中定义的常量,所以不能包含运行时的信息
  • 变量是在运行时初始化
  • interface
    • 如果 interface{} 的类型断言失败,将会产生一个运行时错误
    • If a type exists only to implement an interface and will never have exported methods beyond that interface, the constructor should return an interface value rather than the implementing type.
    • 确保一个结构体已经实现了一个 interface 可以这个写:var _ json.Marshaler = (*RawMessage)(nil)
  • 嵌套结构体
    • When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.
    • Embedding types introduces the problem of name conflicts but the rules to resolve them are simple. First, a field or method X hides any other item X in a more deeply nested part of the type.
    • if the same name appears at the same nesting level, it is usually an error;
    • However, if the duplicate name is never mentioned in the program outside the type definition, it is OK.
  • Do not communicate by sharing memory; instead, share memory by communicating.

Thanos Coding Style Guide

开发 / Review

    • CloseWithErrCapture

      1. [[email protected]]# cat runutil.go
      2. ...
      3. // CloseWithErrCapture runs function and on error return error by argument including the given error (usually
      4. // from caller function).
      5. func CloseWithErrCapture(err *error, closer io.Closer, format string, a ...interface{}) {
      6. merr := errutil.MultiError{}
      7. merr.Add(*err)
      8. merr.Add(errors.Wrapf(closer.Close(), format, a...))
      9. *err = merr.Err()
      10. }
    • 不要使用 panic,如果有依赖用到了,别忘了用 recover 来处理,如果可以,放弃这个依赖吧;
    • 不要在不同的块作用域使用相同的变量名字(if/for 内外)
    • 预先分配好 slice 和 map 的大小
    • 重用 slice 的底层数组,避免重新分配
      • messages = messages[:0] 可以重置 slice
    • 接口应该尽可能小(1-3 个方法)
    • 避免 shallow function(减少不必要的抽象)
    • 如果明确知道一个函数返回的错误无伤大雅,可以用 _ = 忽略
    • 如果一个变量只使用一次,那么不用赋值变量了,直接在用的地方初始化就好了
    • 函数 / 方法的参数,要么全在一行,要么每个参数一行
    • 结构化日志应该结构化一些,不要所有信息都塞在一条日志文本中
  • 使用表驱动测试,这样更易于阅读
  • 不要依赖实时时间做比较,请使用相对时间
  • 请使用 linters
    • go vet
    • golangci-lint
      • deadcode
      • errcheck
      • goconst
      • goimports
      • gosimple
      • govet
      • ineffassign
      • staticcheck
      • structcheck
      • typecheck
      • unused
      • varcheck
  • 不要 print,用 logger
© 2012-2020 路人的技术 版权所有. Powered by LauZoo. Theme based on Nuo.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK