Date post: | 06-May-2015 |
Category: |
Technology |
Upload: | moriyoshi-koizumi |
View: | 6,347 times |
Download: | 0 times |
10~30分で何となくわかる
Go兼ハンズオン資料
提 供
#moriyoshi
Goとは• Plan9の開発者であるKen Thompson, Rob Pike, Russ Coxらが開発した新しいコンパイル型プログラミング言語
• コンパイル言語でありながら動的な型の扱いが可能• Erlangのような並行プログラミングを言語組み込みでサポート
• Dと同じようにネイティブコードに変換して実行する形式を取りつつ、オブジェクトのGCを行う
豆知識①
Q. Goの名前の由来?
A. Googleの「Go」
Erlang →Ericsson Language
Go-Lang →Google Language
という説も...
1. Goをインストール$ export GOROOT=$HOME/go$ export GOBIN=$HOME/go/bin$ export GOOS=linux darwin
$ export GOARCH=amd64 x86
$ export PATH=$GOBIN:$PATH$ mkdir -p $GOBIN$ hg clone -r release \https://go.googlecode.com/hg/ $GOROOT
$ cd $GOROOT/src$ ./all.bash
2. Goのコードを書くpackage mainimport "fmt"
func main() { fmt.Printf("こんにちは、世界!");}
3. Goでコンパイル$ export GOROOT=$HOME/go$ export GOBIN=$HOME/go/bin$ export GOOS=linux$ export GOARCH=amd64$ export PATH=$GOBIN:$PATH$ 6g test.go$ 6l -o test test.6$ ./test
こんにちは、世界!
豆知識②
Q.6gとかの「6」とは何を表しているのでしょう?
会場提供: 日本オラクル(株)
?
A. アーキテクチャ番号(Plan9の伝統)
6: amd648: x865: ARM
ちなみに g は go の g
4. Goで文字列を扱う①package mainimport "fmt"
func main() { str := "こんにちは"; str += "世界"; fmt.Printf("%s\n", str);}
5. Goで配列を扱う①package mainimport "fmt"
func main() { arr := [4]int { 1, 2, 3, 4}; fmt.Printf("0: %d\n", arr[0]); fmt.Printf("1: %d\n", arr[1]); fmt.Printf("2: %d\n", arr[2]); fmt.Printf("3: %d\n", arr[3]);}
6. Goで文字列を扱う②package mainimport "fmt"
func main() { str1 := "Hello, world!"; str2 := "こんにちは, 世界";
fmt.Printf("%s (%d)\n", str1, len(str1)); fmt.Printf("%s\n", str1[0:5]); fmt.Printf("%s (%d)\n", str2, len(str2)); fmt.Printf("%s\n", str2[0:5]); // WTF!}
7. Goで文字列を扱う②package mainimport "fmt"import "utf8"
func main() { str1 := "Hello, world!"; str2 := "こんにちは, 世界";
fmt.Printf("%s (%d)\n", str1, len(str1)); fmt.Printf("%s\n", str1[0:5]); fmt.Printf("%s (%d)\n", str2, utf8.RuneCountInString(str2)); // FIXME: utf8対応のsubstringは用意されていない}
8. Goで繰り返し処理①package mainimport "fmt"
func main() { str := "Hello";
for i, c := range str { fmt.Printf("%d: %c\n", i, c); }}
9. Goで繰り返し処理②package mainimport "fmt"
func main() { str := "Hello";
for i := 0; i < len(str); i += 1 { fmt.Printf("> %c\n", str[i]); }}
10. Goで繰り返し処理③package mainimport "fmt"
func main() { str := "Hello";
i := 0; for { if i >= len(str) { break } fmt.Printf("> %c\n", str[i]); i += 1; }}
11. Goで標準入出力を扱うpackage mainimport "bufio"import "os"import "fmt"
func main() { in := bufio.NewReader(os.Stdin);
for { str, e := in.ReadString('\n'); if e != nil { if e != os.EOF { fmt.Printf("Error: %s\n", e); } break } os.Stdout.WriteString("-> "); os.Stdout.WriteString(str); }}
12. Goで正規表現を扱うpackage mainimport "fmt"import "regexp"
func main() { re, e := regexp.Compile("[A-Z][a-z]+"); if e != nil { fmt.Printf("Error: %s\n", e); return } fmt.Printf("%t\n", re.MatchString("test")); matches := re.MatchStrings("Abc Def "); for i := range matches { fmt.Printf("%s\n", matches[i]); } str := "test Test abc"; fmt.Printf("%s\n", re.ReplaceAllString(str , "***"));}
13. GoでHTTPを扱うpackage mainimport ( "io"; "fmt"; "http")
func main() { url := "http://search.twitter.com/search.json?q=" + http.URLEscape("#moriyoshi"); resp, _, e := http.Get(url); if e != nil { goto Error; } body, e := io.ReadAll(resp.Body); if e != nil { goto Error; } resp.Body.Close(); fmt.Printf(">>> %s\n", string(body)); return;
Error: fmt.Printf("Error: %s\n", e); return;}
14. GoでJSONを扱うpackage mainimport ( "io"; "fmt"; "http"; "json";)
func jsonGet(url string) json.Json { resp, _, e := http.Get(url); if e != nil { goto Error; } body, e := io.ReadAll(resp.Body); if e != nil { goto Error; } resp.Body.Close(); jsonObj, ok, etok := json.StringToJson(string(body)); if !ok { fmt.Printf("JSON syntax error near: " + etok); return nil; } return jsonObj;Error: fmt.Printf("Error: %s\n", e); return nil;}
func main() { url := "http://search.twitter.com/search.json?q=" + http.URLEscape("#moriyoshi"); j := jsonGet(url); results := json.Walk(j, "results"); for i := 0; i < results.Len(); i += 1 { r := results.Elem(i); fmt.Printf("%s: %s\n", r.Get("from_user"), r.Get("text")); } return;}
15. Goroutinepackage mainimport ( "fmt"; "time";)
func sub(n int) { fmt.Printf("Goroutine #%d started.\n", n); for i := 0; i < 5; i += 1 { fmt.Printf("%d: %d\n", n, i); time.Sleep(1e9); }}
func main() { for i := 0; i < 10; i += 1 { go sub(i); } time.Sleep(5e9);}
16. Channelpackage mainimport ( "fmt"; "time";)
func sub(n int, ch chan int) { fmt.Printf("Goroutine #%d started.\n", n); for i := 0; i < 5; i += 1 { fmt.Printf("%d: %d\n", n, i); time.Sleep(1e8); } ch <- n}
func main() { ch := make(chan int); for n := 0; n < 10; n += 1 { go sub(n, ch); time.Sleep(4e8) } for i := 0; i < 10; i += 1 { n := <- ch; fmt.Printf("Goroutine #%d ended.\n", n) }}
17. Struct型を使う①package mainimport ( "fmt";)type Employee struct { name string;}type Company struct { name string; employees []Employee;}
func main() { c := Company { name:"Acme" }; c.employees = []Employee { Employee { name:"Foo" }, Employee { name:"Bar" } };
fmt.Printf("Company name: %s\n", c.name); fmt.Printf("Employees: %d\n", len(c.employees)); for _, employee := range c.employees { fmt.Printf(" %s\n", employee.name); }}
18. Map型を使うpackage mainimport ( "fmt";)
func main() { m := make(map[string] string); m["Foo"] = "Hoge"; m["Bar"] = "Fuga"; for k, v := range m { fmt.Printf("%s: %s\n", k, v) }}
キーの型 値の型
19. Method①package mainimport ( "fmt";)type MyInt int;type Foo struct { values []int;}
func (self *Foo) sum() int { retval := 0; for _, v := range self.values { retval += v } return retval}
func main() { f := &Foo { values: []int { 0, 1, 2, 3, 4 } }; fmt.Printf("%d\n", f.sum());}
20. Method②package mainimport ( "fmt";)type MyInt int;
func (self MyInt) add(rhs int) MyInt { return MyInt(int(self) + rhs)}
func main() { fmt.Printf("%d\n", MyInt(1).add(4).add(5));}
21. Interface①package mainimport ( "fmt")
type IHello interface { sayHello()}
type IKonnichiwa interface { sayKonnichiwa()}
type IBilingual interface { IHello; IKonnichiwa}
type TypeA int;type TypeB int;type TypeC int;
func (_ TypeA) sayHello() {}
func (_ TypeB) sayKonnichiwa() {}
func (_ TypeC) sayHello() {}
func (_ TypeC) sayKonnichiwa() {}
func hello(_ IHello) { fmt.Printf("Hello\n")}func konnichiwa(_ IKonnichiwa) { fmt.Printf("Konnichiwa\n")}
func main() { var ( a TypeA; b TypeB; c TypeC );
hello(a); konnichiwa(b); hello(c); konnichiwa(c);}
22. Struct型②package main
type Foo struct { a int}type Bar struct { b int}type FuBar struct { *Foo; *Bar}
func (_ *Foo) doSomething() {}
func (_ *Bar) doIt() {}
func main() { fubar := new(FuBar); fubar.doSomething(); fubar.doIt()}
23. 無名関数①package main
import "fmt";
func main() { fmt.Printf("%d\n", func(f func(func(int) int) int) int { return f(func(a int) int { return a + 2 }) }(func(g func(int) int) int { return g(1) }));}
24. 無名関数②package mainimport "fmt"
type UntypedFunc func(Any) Any;type Any struct { UntypedFunc; int}
func main() { // Y-combinator result := func(f Any) Any { return func(x Any) Any { return f.UntypedFunc( Any{ UntypedFunc: func(y Any) Any { return x.UntypedFunc(x).UntypedFunc(y) } } ) }( Any{ UntypedFunc: func(x Any) Any { return f.UntypedFunc( Any{ UntypedFunc: func(y Any) Any { return x.UntypedFunc(x).UntypedFunc(y) } } ) } } ); }(Any{ UntypedFunc: func(f Any) Any { return Any{ UntypedFunc: func(n Any) Any { if (n.int == 0) { return Any{ int: 1 } } return Any{ int: f.UntypedFunc(Any{ int: n.int - 1 }).int * n.int } } } } } ); fmt.Printf("%d\n", result.UntypedFunc(Any{ int: 5 }).int);}
25. 配列とスライス①package main
import "fmt";
func sliceInfo(arr []int) { fmt.Printf("len(arr)=%d\n", len(arr)); fmt.Printf("cap(arr)=%d\n", cap(arr));}
func arrayInfo(arr *[4]int) { fmt.Printf("len(arr)=%d\n", len(arr)); fmt.Printf("cap(arr)=%d\n", cap(arr));}
func main() { arr := [4]int { 1, 2, 3, 4 }; arrayInfo(&arr); // doesn't compile // sliceInfo(arr); sliceInfo(&arr); // doesn't compile // arrayInfo(arr[0:2]); sliceInfo(arr[0:2])}
TODO
• 型キャスト• chan の chan 渡し• socket 周り