Effective Go 学习笔记

  • Every package should have a package comment, a block comment preceding the package clause.

  • Every exported (capitalized) name in a program should have a doc comment.

  • 在 Windows 的控制台里,可以用 findstr 来代替 Linux 下的 grep, 例如
    $ godoc regexp | grep parse

    可以用以下命令代替

    $ godoc regexp | findstr parse
  • By convention, packages are given lower case, single-word names; there should be no need for underscores or mixedCaps.

  • Call your string-converter method String not ToString.

  • For strings, the range does more work for you, breaking out individual Unicode code points by parsing the UTF-8. Erroneous encodings consume one byte and produce the replacement rune U+FFFD.

  • It's therefore possible—and idiomatic—to write an if-else-if-else chain as a switch.

  • new(T) allocates zeroed storage for a new item of type T and returns its address, a value of type *T. In Go terminology, it returns a pointer to a newly allocated zero value of type T.
    p := new(SyncedBuffer)  // type *SyncedBuffer
    var v SyncedBuffer      // type  SyncedBuffer
  • make(T, args) applies only to maps, slices and channels and does not return a pointer.

  • If the slices might grow or shrink, they should be allocated independently to avoid overwriting the next line; if not, it can be more efficient to allocate a single array and point the individual slices into it.

  • You can use the catchall format %v (for “value”); the result is exactly what Print and Println would produce.

  •  It's a common and easy mistake to make, as this example shows.
    type MyString string
    func (m MyString) String() string {
        return fmt.Sprintf("MyString=%s", m) // Error: will recur forever.
    }
    

    It's also easy to fix: convert the argument to the basic string type, which does not have the method.

    type MyString string
    func (m MyString) String() string {
        return fmt.Sprintf("MyString=%s", string(m)) // OK: note conversion.
    }
  • iota constant generator https://golang.org/ref/spec#Iotahttps://github.com/golang/go/wiki/Iota

  • The use of Sprintf to implement ByteSize's String method is safe because it calls Sprintf with %f, which is not a string format: Sprintf will only call the String method when it wants a string, and %f wants a floating-point value.

  • init() is called after all the variable declarations in the package have evaluated their initializers.

  • The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers.

  • It's an idiom in Go programs to convert the type of an expression to access a different set of methods.

  • Since we can define a method for any type except pointers and interfaces, we can write a method for a function.

  • Always check error returns; they're provided for a reason.

  • When a program is under active development, the blank identifier provides a workaround.
    var _ = fmt.Printf // For debugging; delete when done.
    var _ io.Reader    // For debugging; delete when done.
    // TODO: use fd.
    _ = fd


  • To import the package only for its side effects, rename the package to the blank identifier:
    import _ "net/http/pprof"
    


  • Only interfaces can be embedded within interfaces.

  • Do not share memory, instead, communicate.
    Do not communicate by sharing memory; instead, share memory by communicating.


  • In Go, function literals are closures.

  • Receivers always block until there is data to receive, if the channel is unbuffered.
    (read more: http://www.cnblogs.com/ahui2017/p/6662401.html)

  • deferred functions can modify named return values. 

  •  the error method (because it's a method bound to a type, it's fine, even natural, for it to have the same name as the builtin error type).
原文地址:https://www.cnblogs.com/ahui2017/p/6393033.html