This is a creation in Article, where the information may have evolved or changed.
Go in Action
Go in action-manning 2016
Directory
- 1 introduction go
- 2 go QuickStart
Li class= "toclevel-1 tocsection-3" > 3 packaging, tools
- 4 arrays, slices, and maps
- 5 go type system
- 6 concurrency
- 7 concurrency mode
- 8 standard library
- 9 Test and performance benchmarks
Introduction to Go
- Fmt. Println ("Hello, World")
- ? Does the book seem to mention go exception handling?
Go Quick Start
- Log. Setoutput (OS. Stdout)//import ("Log" ...)
- Package main//main must be in the main bundle to generate the executable file? Usually named in your directory?
- Func init () {...}
- Func main () {...}
- Search.go
- var matchers = make (Map[string]matcher)
- Go func (matcher matcher, feed *feed) {...} (Matcher, Feed)
- defer file. Close ()//followed by initialization of file, err: = OS. Open (datafile) is in the same scope, which is really a bit simpler than try-finally or using
- Func Match (matcher matcher, Feed *feed, searchterm string, results chan<-*result) {
- Note the parameter declaration of ' write Chan ' here
- What if the * members in the 2 value struct refer to the same object? -Will the count be automatically quoted?
- XMLName XML. Name ' xml: ' item '//And this type?
Packaging, tools
- Remote import:
- the import github.com/spf13/viper//go build command searches the local gopath (eh? Will this result in always downloading to the latest version? may not be compatible)
- name import:
- import (myfmt "mylib/fmt")
- Anonymous import (SQL driver, abbreviated)
li>filename := OS. ARGS[1]
- contents, err := ioutil. ReadFile (filename)//Read all the contents? Don't have an iterator
- go build.
- Go vet//lint tool?
- Go FMT//code cleanliness ...
- godoc-http=:6060
- Dependency Management
- vendoring
- import "Bitbucket.org/ww/goautoneg" to
- "GITHUB.A Rdanstudios.com/myproject/godeps/_workspace/src/bitbucket.org/ww/goautoneg "
- GB The problem with
- import is that no version is specified
- vendored code: $PROJECT/vendor/src/
- is incompatible with Go get
GB Build All
arrays, slices, and maps
- Array
- Array: = [5]int{10, 20, 30, 40, 50}
- Array: = [...] INT{10, 20, 30, 40, 50}//auto-infer array length, dimension once initialized cannot be modified
- Array: = [5]int{1:10, 2:20}//select subscript initialization?
- ARRAY[2] = 35
- Array: = [5]*int{0:new (int), 1:new (int)}//Arrays of pointers
- *ARRAY[0] = 10//In fact, the go language does not strictly distinguish between pointers and references?
- Array1 = array2//array is a value object, the assignment causes the memory copy
- Array2D: = [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
- Pass the address of the array to the function: Func foo (array *[1e6]int) {...}//Note that the array pointer type here is much more straightforward than the C language.
- Slice: Is the encapsulation of the array, addr,length,capacity metadata is provided internally
- slice := make ([]string, 5)
- slice := ma Ke ([]int, 3, 5)
- slice := []string{"Red", "Blue", "Green", "Yellow", "Pink"}//note here [] There are neither length constants nor ... Auto-infer
- newslice := Slice[1:3]//Length 2, Volume 4? Newslice Initial case Reference slice?
- Slice capacity =5,newslice =5-1=4, note that Newslice does not have access to slice[0] elements (This design is interesting!).
- Multiple slice may share a chunk of memory (so the modifications need to be synchronized)
- Slice[index] can only access elements within the length range, to access the capacity range, Requires Append:newslice = Append (newslice)
- when the underlying actual storage is below the new capacity, will append allocate new memory? A little realloc.
- append:length=1000 each time double, otherwise add 25%
- slice := Source[2:3:4]//If yes Start:length:capacity triples (not the kind of syntax in Python)
- iteration: For index, value := range Slice {...}//g o idiomatic method; Think of the enumerate function in Python
- Map
- Dict: = Make (Map[string]int)
- Dict: = map[string]string{"Red": "#da1337", "Orange": "#e95a22"}//Note,: = represents type definition (auto-inference) and initialization
- Dict: = map[[]string]int{}//Compile error: Slice cannot be used as a map key (must execute = = operation), but can be used as map value
- Nil Map question:
- var colors map[string]string
- colors["Red" = "#da1337"//Run-time error
- Can do this: value, exists: = colors["Blue"]//GO usage
- Value: = colors["Blue"]//This is OK, if key does not exist, value returns type 0 values
- Delete (colors, "Coral")//delete element, again built-in function, which differs from the C + + language member function style
- Map does not copy when passed between functions
The Go type system
- var always initializes the variable to a value of 0
- : = Simultaneous declaration and initialization
- Type typeName struct {fields ...}
- Then you can func (a typeName) methodName (args) retType {...} Extension method.
- It can also be written as Func (a *typename) ..., but when the method is called, it is all. number, but the pointer type variable must be &struct{...} Initialized to the
- A typename parameter represents a method that operates on the value type of type, which is the Const method inside C + +?
- A variable of type value can invoke a method defined with a pointer type (these places are too easy for a person to confuse) and will be converted to (&obj). Method ()
- Reference types: Slice, map, channel, interface, func
- ' Header ' value, contains a pointer
- Interfaces
- ' Method sets ' (vtable in C + +?) )
- Is the method pointer in the interface not dynamically populated at runtime???
- The recipient of an interface implementation is usually *t, not the value type of T?
- If you implement an interface with the value T type as the recipient, then the interface can accept T and *t (?) as a parameter. )
- Type embedding
- A bit Ruby/scala mixin style ~
- Inner type promotion//As long as the name does not conflict?
- Exporting and Unexporting identifiers
- Depending on whether the 1th letter of the first name is uppercase or lowercase ...
- I feel this chapter of the author said too much nonsense, in fact, a simple sentence can be said clearly!
Concurrent
- Logical processors?
- When performing blocking IO operation, detach; When IO is ready, attach again?
- A 1th example:
- Runtime. Gomaxprocs (1)//or runtime. NUMCPU ()
- VAR wg sync. Waitgroup//WG's usage can be directly read the document and the sample code to grasp it instantly?
- Wg. ADD (2)
- Go func () {
-
defer WG. Done ()
-
} ()
- Wg. Wait ()
- Scheduler can be interrupted automatically at Goroutines execution time? (Swap out?) Preemptive scheduling? This internal operation occurs in the FMT. When the printf call?
- Competitive conditions
- Read-write shared variables must be atomic;
- Detection Tool: Go build-race
- Method 1:atomic. AddInt64 (&counter, 1) #奇怪, how does the atomic package make a change to a int64 variable is atomic? Take advantage of platform-specific assembly instructions?
- Method 2:mutex Sync. Mutex = mutex. Lock () {...} mutex. Unlock ()
- More flexible, Channels
- Initialization
- Unbuffered: = make (chan int) #如果有一个没准备好, first action (send/Accept) wait
- Buffered: = Make (Chan string, 10)
- Close action: can still be accepted but cannot be sent again (task send originator)
- Send data: Buffered <-"Gopher"
- Accept data: Value: = <-buffered
- Rand. Seed (time. Now (). Unixnano ())
concurrency mode
- Runner: Monitoring run time and timeout termination
- Type Runner struct {
- Interrupt Chan os. Signal
- Complete Chan Error
- Timeout <-chan time. Time
- tasks []func (int)
- var errtimeout = errors. New ("Received timeout")//Pre-created Error object
- Func (R *runner) Add (Tasks ... func (int)) {r.tasks = append (R.tasks, Tasks ...)}//Note the arguments here;
- Func (R *runner) Start () error {//Run All Tasks and monitor time-out errors
- Signal. Notify (R.interrupt, OS. Interrupt)
- Go func () {r.complete <-r.run ()} ()
- Select {
- Case ERR: = <-r.complete:return err
- Case <-r.timeout:return Errtimeout
- Func (R *runner) run () error {...}//executes each task sequentially, slightly
- Func (R *runner) Gotinterrupt () bool {
- Select {
- Case <-r.interrupt: Signal. Stop (R.interrupt) return true//note here to check that there is no acceptance to the operating system interrupt
- The Default:return false//default branch makes the preceding <-r.interrupt operation not block (? Is it possible to lose interrupts?)
- Note that the initialization: Interrupt:make (Chan os. Signal, 1), Timeout:time. After (duration),//To model OS interrupts and timeouts as special Chan
- Pooling
- Type Pool struct {
- M sync. Mutex//This is used to protect what? Chan is not self-synchronizing (protecting the assignment of closed variables??? By
- Resources Chan io. Closer
- Factory func () (IO. Closer, error)//This name is disgusting, it should be changed to Allocnewresource
- closed bool
- Func (P *pool) acquire () (IO. Closer, error) {
- Select {
- Case R, OK: = <-p.resources: ...
- Default:return P.factory ()
- Func (P *pool) Release (R io. Closer) {
- P.m.lock ()
- Defer P.m.unlock ()
- ...
- Select {Case p.resources <-r: ...//default:pool full, releasing resources directly
- Start Goroutine in the loop to prevent sharing the same index/counter variable:
- Go func (a int) {...} (i)
- Work
- Naming a bit of a problem, work () seems to be executework ()?
Standard library
- Http://sourcegraph.com/code.google.com/p/go/.GoPackage/io/.def/Writer, unable to access
- Logging
- Log. Setprefix ("TRACE:")
- Log. SetFlags (log. Ldate | Log. Lmicroseconds | Log. Llongfile)
- Log. PRINTLN/FATALLN/PANICLN ("message")
- const {
- Ldate = 1 << Iota
- Custom logger:
- var (Trace *log. Logger ...)
- Trace = log. New (Ioutil. Discard, "TRACE:", log. Ldate|log. Ltime|log. Lshortfile) # var Discard io. Writer = devnull (0)
- Stdin = NewFile (UIntPtr (syscall. Stdin), "/dev/stdin")//?
- Io. Multiwriter (file, OS. STDERR)//?
- Encoding/decoding
- Gresult struct {
- Gsearchresultclass string ' JSON: Members Within "Gsearchresultclass" '//struct require special JSON mapping declarations (tags metadata);
- ...
- gresponse struct {
-
responsedata struct {
-
Results []gresult ' JSON: "Results" '
-
} ' JSON: ' ResponseData
'
- Decoding:
- var gr gresponse
- Err = json. Newdecoder (resp. Body). Decode (&GR)
- Unmarshal:
- ERR: = json. Unmarshal ([]byte (JSON), &c)//?
- More flexible analysis:?
-
var c map[string]interface{}
-
Err: = json. Unmarshal ([]byte (JSON), &c)//In this case the sense code in
interface{} will be abused?
- Coding
- c: = Make (map[string]interface{})
- ...
- Data, err: = json. marshalindent (c, "", "")
- Input and output
- There seems to be nothing particularly worth saying (another set of API naming styles)
Testing and performance Benchmarks
- Listing01_test.go
- Func testdownload (t *testing. T) {
-
t.Log ("Given the need to test downloading content.") #t. Errorf represents a test failure?
-
...
-
resp, err: = http. Get (URL)
-
defer resp. Body.close ()
- Func Sendjson (rw http. Responsewriter, R *http. Request) {
- U = ...
- rw. Header (). Set ("Content-type", "Application/json")
- rw. Writeheader (200)
- Json. Newencoder (rw). Encode (&u)
- ?
- R, _: = http. Newrequest ("GET", "/sendjson", nil)
- RW: = Httptest. Newrecorder ()
- http. Defaultservemux.servehttp (rw, R)
- Performance Benchmark
- func benchmarksprintf (b *testing. B) {
-
b.resettimer ()
- go test-v-run= "None"-bench= "benchmarksprintf"/ /Number of runs?