Benutzer-Werkzeuge

Webseiten-Werkzeuge


becki:linux:golang

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
becki:linux:golang [2011-02-15 12:45]
becki
becki:linux:golang [2018-02-26 11:24] (aktuell)
becki
Zeile 1: Zeile 1:
-====== Go Programming Language Tips ======+====== Go Programming Language Tips ==
 ===== Setup == ===== Setup ==
  
Zeile 14: Zeile 14:
 #!/bin/sh #!/bin/sh
 export PATH="​$PATH:/​usr/​local/​go/​bin"​ export PATH="​$PATH:/​usr/​local/​go/​bin"​
 +export GOROOT=/​usr/​local/​go
 </​code>​ </​code>​
  
 Go Syntax Highlighting for your editor at http://​go-lang.cat-v.org/​text-editors/​ Go Syntax Highlighting for your editor at http://​go-lang.cat-v.org/​text-editors/​
 +
 +Go Syntax Highlighting for your dokuwiki at http://​rosettacode.org/​wiki/​User:​MizardX/​GeSHi_Go.php (Doesn'​t work with 2009-12-25c "​Lemming"​)
 +
 +Updating Go is described [[golang>​doc/​install.html?​h=weekly+release#​releases|here]]
 +
 +==== ARM5 (Sheevaplug) specific ==
 +
 +  * Current release version (release.r57.1 / 8295:​95d2ce135523) does not work
 +  * Current weekly version (weekly.2011-06-02 / 8624:​3418f22c39eb) works
 +  * ''​export GOARM=5''​ in ''​~/​.profile''​ !
 +  * export GOHOSTARCH=arm,​ export GOHOSTOS=linux,​ export GOARCH=arm, export GOOS=linux may be necessary too
 +
 +==== Build Crosscompiler on x86 for ARM5 ==
 +
 +Export the following variables before running ''​src/​all.bash'':​
 +
 +<code bash>
 +export GOROOT=$(pwd)
 +export GOHOSTARCH=386
 +export GOHOSTOS=linux
 +export GOARCH=arm
 +export GOOS=linux
 +export GOARM=5
 +</​code>​
 +
  
 ===== Hello World == ===== Hello World ==
Zeile 25: Zeile 51:
  
 func main() { func main() {
-    fmt.Printf("​Hallo Süße!\n"​)+    fmt.Printf("​Hallo ​ Süße!\n"​)
 } }
 </​code>​ </​code>​
  
-Build & run: ''​8g hello.go && 8l -o hello hello.8 && ./​hello''​+Build & run:  
 +x86: ''​8g hello.go && 8l -o hello hello.8 ​&& ./​hello''​ 
 + 
 +arm: ''​5g hello.go && 5l -o hello hello.5 ​&& ./​hello''​
  
 For ''​Printf''​ see [[golang>​pkg/​fmt/​]] For ''​Printf''​ see [[golang>​pkg/​fmt/​]]
 +
 +==== Command Line Arguments ==
 +
 +Use the ''​os.Args''​ slice. [[golang>​doc/​go_tutorial.html|Source]]
 +
 +==== Exit Code ==
 +
 +Use ''​os.Exit()''​.
 +
 +''​return''​ in ''​main()''​ only works without any argument, which results in ''​0''​ as exit code (tested).
 +
 +==== Standard Streams ==
 +
 +FIXME
  
 ===== Variable Declaration == ===== Variable Declaration ==
  
-<code go>+<code go> ​
 package main package main
 import "​fmt"​ import "​fmt"​
 func main() { func main() {
     var i,j int                         // 2 ints, autoinitialized to zero value     var i,j int                         // 2 ints, autoinitialized to zero value
-    fmt.Printf("​%d %d\n", i, j)         // 0 0+    fmt.Printf("​%d %d\n", i, j)         // 0 0 
  
     var k,l,m,n= true, 0, 2.6, "​Hello" ​ // missing types default to:     var k,l,m,n= true, 0, 2.6, "​Hello" ​ // missing types default to:
-    fmt.Printf("​%T %T %T %T\n", k,l,m,n)// -> bool int float64 string +    fmt.Printf("​%T %T %T %T\n",​k,​l,​m,​n) // -> bool int float64 string 
-    fmt.Printf("​%v %v %v %v\n", k,l,m,n)// -> true 0 2.6 Hello+    fmt.Printf("​%v %v %v %v\n",​k,​l,​m,​n) // -> true 0 2.6 Hello
     fmt.Println(k,​l,​m,​n) ​               // -> true 0 2.6 Hello     fmt.Println(k,​l,​m,​n) ​               // -> true 0 2.6 Hello
  
     o,p:= false, "​World" ​               // short form: no type but initializers:​     o,p:= false, "​World" ​               // short form: no type but initializers:​
-    fmt.Printf("​%T %T\n", o,p)          // -> bool string+    fmt.Printf("​%T %T\n", o, p)         ​// -> bool string
     fmt.Println(o,​p) ​                   // -> false World     fmt.Println(o,​p) ​                   // -> false World
 } }
Zeile 55: Zeile 98:
 [[golang>​doc/​go_spec.html#​Variable_declarations|more]] [[golang>​doc/​go_spec.html#​Variable_declarations|more]]
  
-===== Arrays ​and Slices ​==+===== Arrays ==
  
 <code go> <code go>
 +a := [...]int{0, 1, 2, 3}           // an array created literally
 +a := [4]int ​                        // create a zeroed array (?)
 +</​code>​
 +
 +<code go> ​
 package main package main
 import "​fmt"​ import "​fmt"​
 func main() { func main() {
-    //var ia= [...]int{47,​11} ​          ​// Create an array literal +    //var ia= [...]int{47,​ 11}      // Create an array literal 
-    ia:= [...]int{47,​11} ​               // Create an array literal - short form+    ia:= [...]int{47,​11} ​           // Create an array literal - short form
  
-    for i, v := range ia {              // Loop through an array+    for i, v := range ia {          // Loop through an array
         fmt.Printf("​%d %d\n", i, v)         fmt.Printf("​%d %d\n", i, v)
     }     }
  
-    var ib [2]int                       ​// Create ​array with ZEROED elements +    var ib [3]int                   ​// Create ​arrays ​with ZEROED elements 
-    for _, v := range ib {              // '​_'​ means key not used +    var ic [2]int 
-        fmt.Printf("​%d ", v)            // -> 0 0+    for _, v := range ib {          // '​_'​ means key not used 
 +        fmt.Printf("​%d ​\n", v)      // -> 0 0
     }     }
-    ​fmt.Printf("​\n"​)+ 
 +    //i=0                           // illegal, i not defined outside loop 
 +    //ib = ia                       // illegal, different len => different types 
 +    //​ib[3]=9 ​                      // illegal, index out of bounds 
 +    //fmt.Println(ia == ic)         // illegal, no == operator for array 
 + 
 +    ic= ia                          // copy BY VALUE 
 +    ia[0]= 36 
 +    fmt.Println(ia,​ ic)             // -> [36 11] [47 11] 
 + 
 +    //i:=3 
 +    //​ib[i]=9 ​                      // panic => runtime index check :-)
 } }
 </​code>​ </​code>​
  
-http://​blog.golang.org/​2011/​01/​go-slices-usage-and-internals.html+<note tip> 
 + 
 +  * The //length// of the array is part of its type and cannot grow 
 +  * Arrays are real types 
 +  * Arrays are copied by value :!: 
 +  * A Pointer to an array is possible (unlike in C where the pointer represents the array) 
 + 
 +</​note>​ 
 + 
 +===== Slices == 
 + 
 +<code go> 
 +s := []int{0, 1, 2, 3}                  // a slice created literally 
 +s := make([]int, 4)                     // create a zerored slice 
 +len(s) // get number of items in slice 
 +cap(s) // get actual slice capacity 
 +</​code>​ 
 + 
 +<code go>  
 +package main 
 +import "​fmt"​ 
 +func main() { 
 +    a:= [...]int{0, 1, 2, 3}            // an array to play with 
 +    sa:= a[:]                           // Create slice from whole array 
 +    sb:= a[:2]                          // Create slice from first part 
 +    sc:= a[2:]                          // Create slice from last part 
 +    fmt.Println(sa,​ len(sa), cap(sa)) ​  // -> [0 1 2 3] 4 4 
 +    fmt.Println(sb,​ len(sb), cap(sb)) ​  // -> [0 1] 2 4(!) 
 +    fmt.Println(sc,​ len(sc), cap(sc)) ​  // -> [2 3] 2 2 
 + 
 +    sa[0]=6 ​                            // all slices point to the same array: 
 +    sb[1]=7 ​                            // 
 +    sc[0]=8 ​                            // 
 +    a[3]= 9                             // 
 +    fmt.Println(a,​ sa, sb, sc)          // -> [6 7 8 9] [6 7 8 9] [6 7] [8 9] 
 + 
 +    //​sb[2]=7 ​                          // panic, although cap is 4! 
 + 
 +    sb= sa                              // A copy points to the same array: 
 +    fmt.Println(a,​ sa, sb)              // -> [6 7 8 9] [6 7 8 9] [6 7 8 9] 
 +    sb[0]=0 ​                            // 
 +    fmt.Println(a,​ sa, sb)              // -> [0 7 8 9] [0 7 8 9] [0 7 8 9] 
 + 
 +    // fmt.Println(sb==sa) ​             // invalid, works only with nil 
 + 
 +    sc= append(sb, 5)                   // append() can create new array: 
 +    fmt.Println(sa,​ sb, sc)             // -> [0 7 8 9] [0 7 8 9] [0 7 8 9 5] 
 +    sa[1]= 1                            // 
 +    sb[2]= 2                            // 
 +    fmt.Println(sa,​ sb, sc)             // -> [0 1 2 9] [0 1 2 9] [0 7 8 9 5] 
 +
 +</​code>​ 
 + 
 +<note tip> 
 +  * Slices are copied //by value// but the internal arrays are copied //by reference// :!: 
 +  * Slices have a length (number of items) and a capacity (length of underlying array(?)) 
 + 
 +</​note>​ 
 +<note important>​Appending to a Slice results in a new slice. The new slice may point to a different array than the original slice.</​note>​ 
 + 
 +[[http://​blog.golang.org/​2011/​01/​go-slices-usage-and-internals.html|more]] 
 + 
 +===== Objects == 
 +==== Copying Objects == 
 + 
 +<code go>  
 +type Point struct { 
 +    x, y int 
 +
 + 
 +func main() { 
 +    p:= Point{} 
 +    fmt.Println(p) ​                     // -> {0 0} 
 + 
 +    c:= p 
 +    p.y= 1 
 +    c.x= 2 
 +    fmt.Println(p,​ c)                   // -> {0 1} {2 0} 
 +
 +</​code>​ 
 + 
 +<note tip>​Objects are copied **by value**</​note>​ 
 + 
 +==== Methods == 
 + 
 +<code go>  
 +/** A method which has a copy of its object as receiver: */ 
 +func (pt Point) SetWithVal(x,​ y int) { 
 +    pt.x= x 
 +    pt.y= y 
 +
 + 
 +/** A method which has a pointer to its object as receiver: */ 
 +func (pt *Point) Set(x, y int) { 
 +    pt.x= x 
 +    pt.y= y 
 +
 + 
 +func main() { 
 +    p:= Point{} 
 + 
 +    /* invoking both methods on an object: */ 
 +    ov:= p 
 +    ov.SetWithVal(1,​ 2)                 // -> SetWithVal operates only on copy!: 
 +    fmt.Println(ov) ​                    // -> {0 0} 
 +    ov.Set(3, 4)                        // -> Set works as expected: 
 +    fmt.Println(ov) ​                    // -> {3 4} 
 + 
 +    /* invoking both methods on pointer to object: */ 
 +    op:= &p 
 +    op.SetWithVal(5,​ 6)                 // -> SetWithVal operates only on copy!: 
 +    fmt.Println(op) ​                    // -> &{0 0} 
 +    op.Set(7, 8)                        // -> Set works as expected: 
 +    fmt.Println(op) ​                    // -> &{7 8} 
 + 
 +    /* As expected, canges to the pointer change also the object pointed to: */ 
 +    fmt.Println(p) ​                     // -> {7 8} 
 +
 +</​code>​ 
 + 
 +<note tip> 
 + 
 +  * In order to really work on the object, the receiver of the method must be a //pointer// to the object, otherwise the method operates ony on an (anonymous) copy. 
 +  * Invoking methods on //pointers to objects// has the same syntax and work the same as invoking the method directly on the object. 
 + 
 +</​note>​ 
 + 
 +==== Interfaces == 
 + 
 +<code go> 
 +type Point struct { 
 +    x, y int 
 +
 + 
 +func (pt Point) SetWithVal(x,​ y int) { 
 +    pt.x= x 
 +    pt.y= y 
 +
 + 
 +func (pt *Point) Set(x, y int) { 
 +    pt.x= x 
 +    pt.y= y 
 +
 + 
 +type SetWithVal_i interface { 
 +    SetWithVal(x,​ y int) 
 +
 + 
 +type Set_i interface { 
 +    Set(x, y int) 
 +
 + 
 +func main() { 
 +    var isp Set_i 
 +    var isv SetWithVal_i 
 +    fmt.Printf("​%T %T\n", isp, isv)     // <nil> <​nil>​ 
 + 
 +    o:= Point{} 
 +    isv= o                              // isv is an independent COPY of o: 
 +    fmt.Printf("​%T\n",​ isv)             // -> main.Point 
 +    o.x= 9                              // but the copy 
 +    isv.SetWithVal(1,​ 1)                // can't be modified via isv: 
 +    fmt.Println(o,​ isv)                 // -> {9 0} {0 0} 
 + 
 +    o= Point{} ​                         // reset to {0 0} 
 +    isv= &​o ​                            // isv now is a POINTER(!) to o: 
 +    fmt.Printf("​%T\n",​ isv)             // -> *main.Point 
 +    o.x= 9                              // updates to object are seen by isv 
 +    isv.SetWithVal(2,​ 2)                // but object can't be modified via isv: 
 +    fmt.Println(o,​ isv)                 // -> {9 0} &{9 0} 
 + 
 +    o= Point{} ​                         // reset to {0 0} 
 +    //isp= o                            // Err! Set_i.Set needs pointer receiver 
 + 
 +    isp= &​o ​                            // isp now points to o: 
 +    fmt.Printf("​%T\n",​ isp)             // -> *main.Point 
 +    isp.Set(3, 3)                       // object can be modified via interface 
 +    o.y= 4                              // and vice versa: 
 +    fmt.Println(o,​ isp)                 // -> {3 4} &{3 4} 
 +
 +</​code>​ 
 + 
 +<note tip> 
 +An Interface can store any value that implemts it. This can be a value //or// a pointer to a value. 
 + 
 +The only way to directly operate on an object via an interface is to 
 +  * Implement the methods of the interface with an object //pointer// as receiver 
 +  * Instantiate the interface with the //adress// of the object 
 + 
 +</​note>​ 
 +<note important>​Some :?: library functions which return an interface in reality return a pointer to an implementation of the interface (see e.g. [[golang>​pkg/​net/#​Listener.Listen|net.Listen]])</​note>​ 
 + 
 +===== Handling Errors == 
 + 
 +Defer, Panic, Recover: http://​blog.golang.org/​2010_08_01_archive.html ⇒ The convention in the Go libraries is that even when a package uses panic internally, its external API still returns explicit ''​os.Error''​ values. 
 + 
 +[[golang>​pkg/​os/#​Error|os.Error]] is the same interface as [[golang>​pkg/​fmt/#​Stringer|fmt.Stringer]],​ i.e. it has a method called ''​String()''​ wich returns a ''​string''​. Thus an instance of os.Error can always be passed to the functions in ''​fmt''​ and ''​log''​ directly, without explicitely calling the ''​String()''​ method. E.g: 
 + 
 +<code go> 
 +if err != nil { 
 +    log.Panic(err) 
 +
 +</​code>​ 
 + 
 +FIXME See [[:​becki:​my:​linux:​exception_handling_in_c]] 
 + 
 +===== Unsorted Things == 
 + 
 +  * Since [[golang>​doc/​go_tutorial.html#​tmp_94|strings are immutable values]] I guess only references are passed around if you pass the type ''​string''​. Thus it probably does not make much sense to use pointers to strings. 
 +  * Seems to be convention that a function returns (among others) ''​os.Error == nil''​ when it succeded (tested) 
 +  * ''​if''​ and ''​switch''​ accept an initialization statement, see [[golang>​doc/​effective_go.html#​if]] 
 +  * Number <=> String conversion is done with [[golang>​pkg/​strconv/​]] 
 +  * [[http://​www.syntax-k.de/​projekte/​go-review|Interesting Go overview]] 
 + 
 +===== Todo == 
 + 
 +  * Where is variable argument list for functions?​ 
 +  * Where is ''​basename''?​ 
 +  * Type Conversions look like function calls, see [[golang>​doc/​go_spec.html#​Conversions]] 
 +  * Check type assertion, eg. ''​s,​ ok := v.(Stringer)'',​ see Tutorial
  
becki/linux/golang.1297773914.txt.gz · Zuletzt geändert: 2011-02-15 12:45 von becki

Impressum - Datenschutzerklärung