43
10~30分で 何となくわかる Go 兼ハンズオン資料

10〜30分で何となく分かるGo

Embed Size (px)

Citation preview

Page 1: 10〜30分で何となく分かるGo

10~30分で何となくわかる

Go兼ハンズオン資料

Page 2: 10〜30分で何となく分かるGo

提 供

#moriyoshi

Page 3: 10〜30分で何となく分かるGo

Goとは• Plan9の開発者であるKen Thompson, Rob Pike, Russ Coxらが開発した新しいコンパイル型プログラミング言語

• コンパイル言語でありながら動的な型の扱いが可能• Erlangのような並行プログラミングを言語組み込みでサポート

• Dと同じようにネイティブコードに変換して実行する形式を取りつつ、オブジェクトのGCを行う

Page 4: 10〜30分で何となく分かるGo

豆知識①

Page 5: 10〜30分で何となく分かるGo

Q. Goの名前の由来?

Page 6: 10〜30分で何となく分かるGo

A. Googleの「Go」

Page 7: 10〜30分で何となく分かるGo

Erlang →Ericsson Language

Go-Lang →Google Language

という説も...

Page 8: 10〜30分で何となく分かるGo

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

Page 9: 10〜30分で何となく分かるGo

2. Goのコードを書くpackage mainimport "fmt"

func main() { fmt.Printf("こんにちは、世界!");}

Page 10: 10〜30分で何となく分かるGo

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

こんにちは、世界!

Page 11: 10〜30分で何となく分かるGo

豆知識②

Page 12: 10〜30分で何となく分かるGo

Q.6gとかの「6」とは何を表しているのでしょう?

Page 13: 10〜30分で何となく分かるGo

会場提供: 日本オラクル(株)

?

Page 14: 10〜30分で何となく分かるGo

A. アーキテクチャ番号(Plan9の伝統)

Page 15: 10〜30分で何となく分かるGo

6: amd648: x865: ARM

ちなみに g は go の g

Page 16: 10〜30分で何となく分かるGo

4. Goで文字列を扱う①package mainimport "fmt"

func main() { str := "こんにちは"; str += "世界"; fmt.Printf("%s\n", str);}

Page 17: 10〜30分で何となく分かるGo

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]);}

Page 18: 10〜30分で何となく分かるGo

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

Page 19: 10〜30分で何となく分かるGo

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は用意されていない}

Page 20: 10〜30分で何となく分かるGo

8. Goで繰り返し処理①package mainimport "fmt"

func main() { str := "Hello";

for i, c := range str { fmt.Printf("%d: %c\n", i, c); }}

Page 21: 10〜30分で何となく分かるGo

9. Goで繰り返し処理②package mainimport "fmt"

func main() { str := "Hello";

for i := 0; i < len(str); i += 1 { fmt.Printf("> %c\n", str[i]); }}

Page 22: 10〜30分で何となく分かるGo

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

Page 23: 10〜30分で何となく分かるGo

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

Page 24: 10〜30分で何となく分かるGo

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 , "***"));}

Page 25: 10〜30分で何となく分かるGo

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

Page 26: 10〜30分で何となく分かるGo

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

Page 27: 10〜30分で何となく分かるGo

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

Page 28: 10〜30分で何となく分かるGo

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

Page 29: 10〜30分で何となく分かるGo

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}

Page 30: 10〜30分で何となく分かるGo

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

Page 31: 10〜30分で何となく分かるGo

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

Page 32: 10〜30分で何となく分かるGo

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

キーの型 値の型

Page 33: 10〜30分で何となく分かるGo

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());}

Page 34: 10〜30分で何となく分かるGo

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

Page 35: 10〜30分で何となく分かるGo

21. Interface①package mainimport ( "fmt")

type IHello interface { sayHello()}

type IKonnichiwa interface { sayKonnichiwa()}

type IBilingual interface { IHello; IKonnichiwa}

Page 36: 10〜30分で何となく分かるGo

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

Page 37: 10〜30分で何となく分かるGo

func main() { var ( a TypeA; b TypeB; c TypeC );

hello(a); konnichiwa(b); hello(c); konnichiwa(c);}

Page 38: 10〜30分で何となく分かるGo

22. Struct型②package main

type Foo struct { a int}type Bar struct { b int}type FuBar struct { *Foo; *Bar}

Page 39: 10〜30分で何となく分かるGo

func (_ *Foo) doSomething() {}

func (_ *Bar) doIt() {}

func main() { fubar := new(FuBar); fubar.doSomething(); fubar.doIt()}

Page 40: 10〜30分で何となく分かるGo

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

Page 41: 10〜30分で何となく分かるGo

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

Page 42: 10〜30分で何となく分かるGo

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

Page 43: 10〜30分で何となく分かるGo

TODO

• 型キャスト• chan の chan 渡し• socket 周り