旅行しながら働く ムラサメ研究所社長ブログ

主にゲームやプログラミングのログ

Golang 試食 Part2

Class

そんなものはない
が、C言語で使うような構造体ポインタを明示的に渡す事で、ステートを持たせ同じことが出来る

// 構造体の作成。C言語と違い関数の定義は必要ない
hoge:= &Hoge{
    name: "Name",
}

// メソッドを呼ぶ
hoge.Print()
// Print関数の定義。 h *Hogeで Thisポインタ的なものを定義
func (h *Hoge) Print() {
    // h.name と、明示的にインスタンスを指定する必要がある
    log.Printf("name= [%s]", h.name)
}

その他、インタフェース的なものや、派生的なものもあり、ダックタイピングではあるがオブジェクト指向のようなことができる
Goのオブジェクト指向に関しては、一度まとめて整理したいところ

Goルーチン

Go言語の特徴であるGoルーチン
目的は 並列処理である
ライトウエイトプロセスを使い、シングルスレッドで非同期に処理を行う
go ほげほげ でライトウエイトプロセスを作成する
非同期なのでこの命令を読んだあと即座に処理が戻ってくるので、チャンネルを使い GoルーチンをWaitする
大雑把に Goルーチンが処理を終えシグナルを出すまでWaitすると思っていいだろう
例題だしたいが、後ほどちゃんと調査したい

WaitGrout

    wait := sync.WaitGroup{}
    wait.Add(1)

    go func() {
        defer wait.Done()
       ほげほげ
    }()

    wait.Wait()

Channel

    ch := make(chan struct{})
  
    go func(){
        ほげほげ
        ch <- struct{}{}
    }

プラグイン

Golangプラグイン(共有ライブラリ)機能がある
動的に共有ライブラリ(.so .dll的な)を読み込むことが出来るので
本体をビルドしなおさずに機能の追加、修正が出来る
ただし、現在は64Bit Linuxでしか対応していないため、Windowsネイティブではプラグインを作れない

// pluginライブラリを使い 読み込む
p, err := plugin.Open("path to .so")
if err != nil {
    log.Printf("fail to load plugin")
    return
}

// hoge関数を探す。もちろん メンバ変数も取得可能
hoge, e := p.Lookup("hoge")
if e != nil {
    log.Printf("fail to Lookup 'hoge'")
    return
}

// hoge関数を呼ぶが、interface型なので Castして使う必要がある。今回は func(string) string 型の関数を呼び出す
hoge.(func([]string) string)("var")

interface型、関数ポインタの型キャスト、その他色々と面倒ではあるが便利

ビルド方法は
go build --buildmode=plugin
と、 buildmodeを指定すれば良い