/var/log/messages

debugging with sixth sense

Go のメモ

チュートリアルで云々より

環境まわりを色々確認な必要があるのかどうか。

gomobile

  • Android も iOS も API を全て網羅している訳ではなさげ
  • 本家見るに experimental という文言が

Exercise: Errors にて

以下な記述があります。

a call to fmt.Sprint(e) inside the Error method will send the program into an infinite loop. You can avoid this by converting e first: fmt.Sprint(float64(e)). Why?

何故だろう。何故に無限ループなのかと。

OSX に導入してみる

download ページから go1.2.1.darwin-amd64-osx10.8.pkg を選択して導入。/usr/local/go ができてます。PATH に /usr/local/go/bin を加えるのか。

で、暫く How to Write Go Code を確認。一通りさらってみましたがなかなか良いです。特にテストが楽ちんに書けて実行できるのが良いです。

Exercise: HTTP Handlers

以下なカンジのソレがでっちあがった。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import {
    "fmt"
    "log"
    "net/http"
}

type String string

type Struct struct {
    Greeting string
    Punct string
    Who string
}

func (s String) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, s)
}

fund (s Struct) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprintf(w, "%v %v %v", s.Greeting, s.Punct, s.Who)
}

func main() {
    http.Handle("/string", String("I'm a frayed knot."))
    http.Handle("/struct", &Struct("Hello", ":", "Gophers!"))

    log.Fatal(http.ListenAndServe("localhost:4000", nil))
}

exercise: Equivalent Binary Tree

ヤッてみます。とりあえず以下。

1
$ go get golang.org/x/tour/tree

$GOPATH/src/golang.org ができていました。あと、とりあえず以下な試験を書きました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package treeex

import (
    "testing"
    "golang.org/x/tour/tree"
)    

func TestWalk(t *testing.T) {
    var val = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

    c := make(chan int、 10)
    go Walk(tree.New(1), c)

    for i, v := range val {
        if x := <-c; v != x {
            t.Errorf("Tree[%v] = %v, want %v", i, x, v)
        }
    }
}

これで試験失敗を確認してます。channel の make で 10 指定とかあてずっぽうなのですがxD

そして以下な実装で試験がパスしてるんですがこれ大丈夫なの?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package treeex

func Walk(t *tree.Tree, ch chan int) {
    if t.Left != nil {
        Walk(t.Left, ch)
        ch <- t.Value
        if t.Right != nil {
            Walk(t.Right, ch)
        }
    } else {
        ch <- t.Value
        if t.Right != nil {
            Walk(t.Right, ch)
        }
    }
}

パスはしていますが何となく微妙なカンジ。次は以下な Same の試験を書いたり。

1
2
3
4
5
6
7
8
9
10
11
func TestSameReturnsTrue(t *testing.T) {
    if true != Same(tree.New(1), tree.New(1)) {
        t.Errorf("Same(tree.New(1), tree.New(1)) returns false, wants true")
    }
}

func TestSameReturnsFalse(t *testing.T) {
    if false != Same(tree.New(1), tree.New(2)) {
        t.Errorf("Same(tree.New(1), tree.New(2)) returns true, wants false")
    }
}

現状、Same は固定で false を戻しているので一つの試験がパスしない状態です。

つうか

Walk で channel を close しなきゃいけないみたいなんだけど、どうやって判断するのか分からず挫折なう。

ぐぬぬ

Same ですが試験にパスする実装が書けました。close は手続きオブジェクトを無理やり作れば良いみたい。

1
2
3
4
go func() {
    Walk(t1, c1)
    close(c1)
}

そして Same の実装が以下です。微妙なのは分かってるのですがちょっと膝かっくんされた感満点です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
func Same(t1, t2 *tree.Tree) bool {
    c1 := make(chan int, 10)
    c2 := make(chan int, 10)

    go func() {
        Walk(t1, c1)
        close(c1)
    }
    go finc() {
        Walk(t2, c2)
        close(c2)
    }

    for {
        x, xok := <-c1
        y, yok := <-c2

        if (xok && yok) {
            if (x != y) {
                return false
            }
        } else {
            if (!xok && !yok) {
                return true
            }
            return false
        }
    }
    return true
}

微妙。そして Exercise: Web Crawler はスタンドアロンで実行可能そう。同じ URL にアクセスすな、というのがアレですね。

Comments