Benutzer-Werkzeuge

Webseiten-Werkzeuge


becki:linux:golang

Dies ist eine alte Version des Dokuments!


Go Programming Language Tips

Setup

Download Go source:

cd /usr/local
hg clone -r release https://go.googlecode.com/hg/ go

Build Toolchain:

cd go/src
./all.bash

Add Go tools to PATH by creating /etc/profile.de/go.sh:

#!/bin/sh
export PATH="$PATH:/usr/local/go/bin"

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 here

Hello World

package main
import "fmt"
 
func main() {
    fmt.Printf("Hallo  Süße!\n")
}

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 pkg/fmt/

Command Line Arguments

Use the os.Args slice. 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

package main
import "fmt"
func main() {
    var i,j int                         // 2 ints, autoinitialized to zero value
    fmt.Printf("%d %d\n", i, j)         // 0 0 
 
    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("%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
 
    o,p:= false, "World"                // short form: no type but initializers:
    fmt.Printf("%T %T\n", o, p)         // -> bool string
    fmt.Println(o,p)                    // -> false World
}

more

Arrays

a := [...]int{0, 1, 2, 3}           // an array created literally
a := [4]int                         // create a zeroed array (?)
package main
import "fmt"
func main() {
    //var ia= [...]int{47, 11}      // Create an array literal
    ia:= [...]int{47,11}            // Create an array literal - short form
 
    for i, v := range ia {          // Loop through an array
        fmt.Printf("%d %d\n", i, v)
    }
 
    var ib [3]int                   // Create arrays with ZEROED elements
    var ic [2]int
    for _, v := range ib {          // '_' means key not used
        fmt.Printf("%d \n", v)      // -> 0 0 0
    }
 
    //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 :-)
}
  • 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)

Slices

s := []int{0, 1, 2, 3}                  // a slice created literally
s := make([]int, 4)                     // create a zerored slice
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]
}
  • 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(?))
Appending to a Slice results in a new slice. The new slice may point to a different array than the original slice.

more

Objects

Copying Objects

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}
}
Objects are copied by value

Methods

/** 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}
}
  • 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.

Interfaces

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}
}
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

Error Handling

> The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values.

Unsorted Things

  • 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 doc/effective_go.html#if
  • Number ⇔ String conversion is done with pkg/strconv/

Todo

  • Where is variable argument list for functions?
  • Where is basename?
  • Type Conversions look like function calls, see doc/go_spec.html#Conversions
  • Check type assertion, eg. s, ok := v.(Stringer), see Tutorial
Cookies helfen bei der Bereitstellung von Inhalten. Diese Website verwendet Cookies. Mit der Nutzung der Website erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Computer gespeichert werden. Außerdem bestätigen Sie, dass Sie unsere Datenschutzerklärung gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website. Weitere Information
becki/linux/golang.1307636140.txt.gz · Zuletzt geändert: 2011-06-09 16:15 von becki

Impressum - Datenschutzerklärung