golang
TRANSCRIPT
![Page 1: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/1.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Effective Go[1]
Jongseok Choi
Effective Go Jongseok Choi 1 / 31
![Page 2: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/2.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Outline
1 IntroductionExample
2 Formatting
3 Commentary
4 NamesPackage namesGettersInterface namesMixedCaps
5 Semicolons
6 Control structuresIfRedeclaration and reassignmentForSwitchType switch
7 FunctionsMultiple return valuesNamed result parametersDefer
Effective Go Jongseok Choi 2 / 31
![Page 3: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/3.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Introduction
What is Go?
Although it borrows ideas from existing languages, it has unusual properties thatmake effective Go programs different in character from programs written in itsrelatives.
A straightforward translation of a C++ or Java program into Go is unlikely toproduce a satisfactory result.
In other words, to write Go well, it’s important to understand its properties andidioms.
Effective Go Jongseok Choi 3 / 31
![Page 4: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/4.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Example
Example
The Go package sources1 are intended to serve not only as the core library but also asexamples of how to use the language.
1https://golang.org/src/
Effective Go Jongseok Choi 4 / 31
![Page 5: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/5.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Formatting
Formatting issues are the most contentious but the least consequential.
With Go we take an unusual approach and let the machine take care of mostformatting issues.
The gofmt reads a Go program and emits the source in a standard style ofindentation and vertical alignment, retaining and if necessary reformattingcomments.
1 type T struct {2 name string // name of the object3 value int // its value4 }
Code 1: Unformatted Go code
1 type T struct {2 name string // name of the object3 value int // its value4 }
Code 2: Formatted Go code
Effective Go Jongseok Choi 5 / 31
![Page 6: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/6.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Formatting
IndentationWe use tabs for indentation and gofmt emits them by default. Use spaces only if youmust.
Line lengthGo has no line length limit. Don’t worry about overflowing a punched card. If a linefeels too long, wrap it and indent with an extra tab.
ParenthesesGo needs fewer parentheses than C and Java: control structures (if, for, switch) do nothave parentheses in their syntax. Also, the operator precedence hierarchy is shorter andclearer, so
1 x<<8 + y<<16
Code 3: Operator precedence
Effective Go Jongseok Choi 6 / 31
![Page 7: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/7.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Commentary
Comments style
C-style /* */ block
C++-style // line
The program godoc processes Go source files to extract documentation about the con-tents of the package.
For multi-file packages, the package comment only needs to be present in onefile, and any one will do.
1 /*2 Package regexp implements a simple library for regular expressions .34 The syntax of the regular expressions accepted is:56 regexp:7 concatenation { ’|’ concatenation }8 concatenation :9 { closure }
10 closure:11 term [ ’*’ | ’+’ | ’?’ ]12 term:13 ’^’14 ’$’15 ’.’16 character17 ’[’ [ ’^’ ] character -ranges ’]’18 ’(’ regexp ’)’19 */20 package regexp
Effective Go Jongseok Choi 7 / 31
![Page 8: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/8.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Commentary
If the package is simple, the package comment can be brief.
Depending on the context, godoc might not even reformat comments, so makesure they look good straight up.
Inside a package, any comment immediately preceding a top-level declarationserves as a doc comment for that declaration.
The first sentence should be a one-sentence summary that starts with the namebeing declared.
1 // Package path implements utility routines for2 // manipulating slash - separated filename paths.
1 // Compile parses a regular expression and returns , if successful ,2 // a Regexp that can be used to match against text.3 func Compile(str string) (*Regexp , error) {
Effective Go Jongseok Choi 8 / 31
![Page 9: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/9.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Commentary
Imagine you couldn’t remember the name “Compile” but were looking for the parsingfunction for regular expressions.
If all the doc comments in the package began, ”This function...”, grep wouldn’thelp you remember the name.
1 $ godoc regexp | grep parse2 Compile parses a regular expression and returns , if successful , a Regexp
parsed. It simplifies safe initialization of global variables holdingcannot be parsed. It simplifies safe initialization of global variables
Effective Go Jongseok Choi 9 / 31
![Page 10: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/10.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Commentary
Go’s declaration syntax allows grouping of declarations.
A single doc comment can introduce a group of related constants or variables.
Grouping can also indicate relationships between items, such as the fact that aset of variables is protected by a mutex.
1 // Error codes returned by failures to parse an expression .2 var (3 ErrInternal = errors.New("regexp: internal error")4 ErrUnmatchedLpar = errors.New("regexp: unmatched ’(’")5 ErrUnmatchedRpar = errors.New("regexp: unmatched ’)’")6 ...7 )
1 import "sync"23 var (4 countLock sync.Mutex5 inputCount uint326 outputCount uint327 errorCount uint328 )
Effective Go Jongseok Choi 10 / 31
![Page 11: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/11.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Package names
Package names
When a package is imported, the package name becomes an accessor for the contents.
By convention, packages are given lower case, single-word names.there should be no need for underscores or mixedCaps.
Another convention is that the package name is the base name of its sourcedirectory.
the package in src/encoding/base64 is imported as ”encoding/base64” but has namebase64.
1 import "encoding/base64"
Use the package structure to help you choose good names.
Another short example is once.Do.once.Do(setup) reads well and would not be improved by writingonce.DoOrWaitUntilDone(setup)
Long names don’t automatically make things more readable.
A helpful doc comment can often be more valuable than an extra long name.
Effective Go Jongseok Choi 11 / 31
![Page 12: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/12.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Getters
Getters
Go doesn’t provide automatic support for getters and setters.
There’s nothing wrong with providing getters and setters yourself.
But it’s neither idiomatic nor necessary to put Get into the getter’s name.
If you have a field called owner (lower case, unexported).
The getter method should be called Owner (upper case, exported), not GetOwner.
A setter function, if needed, will likely be called SetOwner.
1 owner := obj.Owner ()2 if owner != user {3 obj.SetOwner(user)4 }
Effective Go Jongseok Choi 12 / 31
![Page 13: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/13.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Interface names
Interface names
By convention, one-method interfaces are named by the method name plus an -ersuffix or similar modification to construct an agent noun
Reader, Writer, Formatter, CloseNotifier etc.
There are a number of such names and it is productive to honor them and the functionnames they capture.
To avoid confusion, do not give your method one of those names unless it has thesame signature and meaning.
If your type implements a method with the same meaning as a method on awell-known type.
Give it the same name and signature call your string-converter method String notToString.
Effective Go Jongseok Choi 13 / 31
![Page 14: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/14.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
MixedCaps
MixedCaps
Finally, the convention in Go is to use MixedCaps or mixedCaps rather thanunderscores to write multiword names.
Effective Go Jongseok Choi 14 / 31
![Page 15: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/15.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Semicolons
Like C, Go’s formal grammar uses semicolons to terminate statements
But unlike in C, those semicolons do not appear in the source.
Instead the lexer uses a simple rule to insert semicolons automatically as it scans,so the input text is mostly free of them.
Semicolons insertion rules
if the newline comes after a token that could end a statement, insert a semicolon.
1 break continue fallthrough return ++ -- ) }
A semicolon can also be omitted immediately before a closing brace, so astatement such as for
1 go func() { for { dst <- <-src } }()
Effective Go Jongseok Choi 15 / 31
![Page 16: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/16.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Semicolons
One consequence of the semicolon insertion rules is that you cannot put the openingbrace of a control structure (if, for, switch, or select) on the next line.
1 if i < f() {2 g()3 }
1 if i < f() // wrong!2 { // wrong!3 g()4 }
Effective Go Jongseok Choi 16 / 31
![Page 17: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/17.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Control structures
The control structures of Go are related to those of C but differ in important ways.
There is no do or while loop, only a slightly generalized for.
if and switch accept an optional initialization statement like that of for/
break and continue statements take an optional label to identify what to breakor continue.
there are new control structures including a type switch and a multiwaycommunications multiplexer, select.
There are no parentheses and the bodies must always be brace-delimited.
Effective Go Jongseok Choi 17 / 31
![Page 18: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/18.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
If
If
In Go,
Mandatory braces.
if and switch accept an initialization statement.
The unnecessary else is omitted.
1 if x > 0 {2 return y3 }
1 if err := file.Chmod (0664); err != nil {2 log.Print(err)3 return err4 }
Effective Go Jongseok Choi 18 / 31
![Page 19: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/19.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Redeclaration and reassignment
Redeclaration and reassignment
In a := declaration a variable v may appear even if it has already been declared,provided:
This declaration is in the same scope as the existing declaration of v (if v isalready declared in an outer scope, the declaration will create a new variable §)
The corresponding value in the initialization is assignable to v.
There is at least one other variable in the declaration that is being declared anew.
1 f, err := os.Open(name)2 d, err := f.Stat()
Effective Go Jongseok Choi 19 / 31
![Page 20: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/20.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
For
For
The Go for loop is similar to—but not the same as—C’s.
It unifies for and while and there is no do-while.
There are three forms, only one of which has semicolons.
1 // Like a C for2 for init; condition; post {3 }45 // Like a C while6 for condition {7 }89 // Like a C for (;;)
10 for {11 }
Effective Go Jongseok Choi 20 / 31
![Page 21: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/21.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
For
For
If you’re looping over an array, slice, string, or map, or reading from a channel, a rangeclause can manage the loop.
If you only need the first item in the range (the key or index), drop the second:“key := range m.”
If you only need the second item in the range (the value), use the blank identifier,an underscore, to discard the first: “ ,value := range m”
1 for key , value := range oldMap {2 newMap[key] = value3 }
Effective Go Jongseok Choi 21 / 31
![Page 22: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/22.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
For
For
Finally,
Go has no comma operator and ++ and – are statements not expressions.
if you want to run multiple variables in a for you should use parallel assignment.
1 // Reverse a2 for i, j := 0, len(a) -1; i < j; i, j = i+1, j-1 {3 a[i], a[j] = a[j], a[i]4 }
Effective Go Jongseok Choi 22 / 31
![Page 23: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/23.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Switch
Switch
Go’s switch is more general than C’s.
The expressions need not be constants or even integers.
The cases are evaluated top to bottom until a match is found.
If the switch has no expression it switches on true.
It’s therefore possible to write an if-else-if-else chain as a switch.
1 func unhex(c byte) byte {2 switch {3 case ’0’ <= c && c <= ’9’:4 return c - ’0’5 case ’a’ <= c && c <= ’f’:6 return c - ’a’ + 107 case ’A’ <= c && c <= ’F’:8 return c - ’A’ + 109 }
10 return 011 }
Effective Go Jongseok Choi 23 / 31
![Page 24: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/24.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Switch
Switch
There is no automatic fall through, but cases can be presented in comma-separatedlists.
1 func shouldEscape(c byte) bool {2 switch c {3 case ’ ’, ’?’, ’&’, ’=’, ’#’, ’+’, ’%’:4 return true5 }6 return false7 }
Effective Go Jongseok Choi 24 / 31
![Page 25: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/25.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Switch
Switch
Loop escape
Go that can be accomplished by putting a label on the loop and “breaking” tothat label.
The continue statement also accepts an optional label but it applies only toloops.
1 Loop:2 for n := 0; n < len(src); n += size {3 switch {4 case src[n] < sizeOne:5 if validateOnly {6 break7 }8 size = 19 update(src[n])
1011 case src[n] < sizeTwo:12 if n+1 >= len(src) {13 err = errShortInput14 break Loop15 }16 if validateOnly {17 break18 }19 size = 220 update(src[n] + src[n+1]<<shift)21 }22 }
1 // Compare returns an integer comparing the two byte slices ,2 // lexicographically .3 // The result will be 0 if a == b, -1 if a < b, and +1 if a > b4 func Compare(a, b []byte) int {5 for i := 0; i < len(a) && i < len(b); i++ {6 switch {7 case a[i] > b[i]:8 return 19 case a[i] < b[i]:
10 return -111 }12 }13 switch {14 case len(a) > len(b):15 return 116 case len(a) < len(b):17 return -118 }19 return 020 }
Code 4: Using slice in switch
Effective Go Jongseok Choi 25 / 31
![Page 26: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/26.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Type switch
Type switch
A switch can also be used to discover the dynamic type of an interface variable.
Such a type switch uses the syntax of a type assertion with the keyword type
inside the parentheses.
1 var t interface {}2 t = functionOfSomeType ()3 switch t := t.(type) {4 default:5 fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t
has6 case bool:7 fmt.Printf("boolean %t\n", t) // t has type bool8 case int:9 fmt.Printf("integer %d\n", t) // t has type int
10 case *bool:11 fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool12 case *int:13 fmt.Printf("pointer to integer %d\n", *t) // t has type *int14 }
Effective Go Jongseok Choi 26 / 31
![Page 27: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/27.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Multiple return values
Multiple return values
One of Go’s unusual features is that functions and methods can return multiplevalues.
This form can be used to improve on a couple of clumsy idioms in C programs.in-band error returns such as -1 for EOF and modifying an argument passed by address.
1 func (file *File) Write(b []byte) (n int , err error)
1 func nextInt(b []byte , i int) (int , int) {2 for ; i < len(b) && !isDigit(b[i]); i++ {3 }4 x := 05 for ; i < len(b) && isDigit(b[i]); i++ {6 x = x*10 + int(b[i]) - ’0’7 }8 return x, i9 }
Effective Go Jongseok Choi 27 / 31
![Page 28: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/28.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Named result parameters
Named result parameters
The return or result “parameters” of a Go function can be given names and used asregular variables, just like the incoming parameters.
When named, they are initialized to the zero values for their types when thefunction begins.
1 func ReadFull(r Reader , buf []byte) (n int , err error) {2 for len(buf) > 0 && err == nil {3 var nr int4 nr, err = r.Read(buf)5 n += nr6 buf = buf[nr:]7 }8 return9 }
Effective Go Jongseok Choi 28 / 31
![Page 29: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/29.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Defer
Defer
Go’s defer statement schedules a function call (the deferred function) to be runimmediately before the function executing the defer returns.
It’s an unusual but effective way to deal with situations such as resources thatmust be released regardless of which path a function takes to return.
Deferring a call to a function such as Close has two advantages.
First, it guarantees that you will never forget to close the file.
Second, it means that the close sits near the open.
1 // Contents returns the file ’s contents as a string.2 func Contents(filename string) (string , error) {3 f, err := os.Open(filename)4 if err != nil {5 return "", err6 }7 defer f.Close() // f.Close will run when we’re finished.89 var result []byte
10 buf := make ([]byte , 100)11 for {12 n, err := f.Read(buf [0:])13 result = append(result , buf[0:n]...) // append is discussed
later.14 if err != nil {15 if err == io.EOF {16 break17 }18 return "", err // f will be closed if we return here
.19 }20 }21 return string(result), nil // f will be closed if we return here.22 }
Effective Go Jongseok Choi 29 / 31
![Page 30: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/30.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Defer
Defer
The arguments to the deferred function are evaluated when the defer executes, notwhen the call executes.
Deferred functions are executed in LIFO order.
1 for i := 0; i < 5; i++ {2 defer fmt.Printf("%d ", i)3 }
A more plausible example is a simple way to trace function execution through theprogram.
1 func trace(s string) { fmt.Println("entering:", s) }2 func untrace(s string) { fmt.Println("leaving:", s) }34 // Use them like this:5 func a() {6 trace("a")7 defer untrace("a")8 // do something ....9 }
Effective Go Jongseok Choi 30 / 31
![Page 31: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/31.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Defer
Defer
We can do better by exploiting the fact that arguments to deferred functions areevaluated when the defer executes.
1 func trace(s string) string {2 fmt.Println("entering:", s)3 return s4 }56 func un(s string) {7 fmt.Println("leaving:", s)8 }9
10 func a() {11 defer un(trace("a"))12 fmt.Println("in a")13 }1415 func b() {16 defer un(trace("b"))17 fmt.Println("in b")18 a()19 }2021 func main() {22 b()23 }
Result
e n t e r i n g : bi n be n t e r i n g : ai n al e a v i n g : al e a v i n g : b
Effective Go Jongseok Choi 31 / 31
![Page 32: Golang](https://reader031.vdocuments.pub/reader031/viewer/2022030308/58ed3a941a28abf6798b45dd/html5/thumbnails/32.jpg)
Introduction Formatting Commentary Names Semicolons Control structures Functions
Defer
Google.Effective go, Mar. 2017.
Effective Go Jongseok Choi 31 / 31