Friday, November 19, 2010

golangのsliceコピー

goパッケージのアップデートがどうやら激しいようで、
hg updateかけないと仕様のページ書いてあることも実行でないようです。

今日は、goパッケージのアップデートにより使用可能となりました、
copy(dst, src []T)についてご説明。

go言語の「スライス」がもっと便利になればいいのに!
そう思っていた人も多いはず。

そこで、まずappendが使用可能になりました!
これで使用頻度は5割増しだ。

文法は
append(アペンドされるスライス, アペンドするオブジェクト)でございます。

var a []int{0,1,2}
b := append(a, 3)
// b == []int{0, 1, 2, 3}

次にcopyが可能になりました。
早速スライスをコピーして別のスライスを用意していじって見ましょう。
文法は
copy(コピー先スライス, コピー元スライス)でございます。

【まずは失敗作1】
var a []int{0,1,2}
b := a
edit(a); output(a); output(b)

ぉ、スライスはポインタであるらしいことを忘れていました!
だから、ポインタをコピーしても、元のaとbは同じものを参照しているのです。

【次に失敗作2】
var a []int{0, 1, 2}
b := a
copy(a, b)
edit(a); output(a); output(b)

もちろんこれでもだめ。
bはただのaのコピーロボット。
aの実体が編集されればbも編集されているということ。

【成功例】
var a []int{0, 1, 2}
b := make([]int(len(a))
copy(b, a)
edit(a); output(a); output(b)


これでaとbは違う実体を持つことができる。
これでこそコピー

Saturday, November 06, 2010

[Go]パッケージを作る

Goにおいて、「パッケージ=外部のgoソースファイルから参照できる関数や構造体などの集合」です。

関数をパッケージにする、つまり関数を外部から参照させるには、
下記の作業をします。

1.ファイル先頭に"package <パッケージ名>"を挿入。
 (package mainと書いてある既存ソースなら、mainを<パッケージ名>に置換)
2.関数の名前の先頭を大文字にする。

これだけです。

既存ソースからの改変を例にすると、
既存ソースが下記であれば

package main

func test() {
//これをパッケージ化
return
}

パッケージ化するとこのようになります。

package test

func Test() {
//これをパッケージ化
return
}


これを外部ファイルから参照するときは

1.import <パッケージ名>を追加
2.<パッケージ名>.<関数名>で参照

以上です。簡単です。

Sunday, February 07, 2010

goroutine強制終了

最近goにはまっています。
チャンネルという新しい同期、非同期通信の仕組みや関数の複数値返し、
待ってたものがやっときたという感じです。

ずんWiki - golang/逆引き/goroutineを終了するには

goで遊んでいてわからなくなったポイントがありました。
go func()で簡単に走らせることができるgoのスレッド、goroutine。
自分のスレッドを強制的に終わらせるために用意された、グローバルな関数がありました。
runtime.Goexit()
上記を参照しました。

下記のようなときに使えます。

例:チャンネルを使ってgoroutineが終わるのを待ちますが、
  強制終了されちゃうとチャンネル受信ができないので終われません。
  ひたすら待ち続けてプロセスが死んじゃいます、という例:


package main
import (
"fmt";
"runtime"
)
var ch= make(chan int, 1);
func main() {
go func() {
func() {
fmt.Printf("Stop goroutine1\n");
runtime.Goexit();
}();
ch <- 1;
}();
<-ch;
}



出力:エラー吐いてプロセス死亡・・・


package main
import (
"fmt";
// "runtime"
)
var ch= make(chan int, 1);
func main() {
go func() {
func() {
fmt.Printf("Stop goroutine1\n");
// runtime.Goexit();
}();
ch <- 1;
}();
<-ch;
}


出力:Stop goroutine1

久しぶりのラーメン

晩御飯に、近くのラーメン屋さんに行きました。
いきなりラーメンを食べたいなどと妻が言うもので、
自分もすっかりラーメン気分になり、
開店前にお店についてしまう始末。
そこは、webでは結構評判がよかったお店。
食べた後、妻は「麺はよかったがスープは微妙」とのこと。
自分はスープが冷たかったのが微妙と思いました。
今日は、ゆったりの土曜日でした。