PHPerでも書けるgo言語
超簡単なお仕事がはいってきたんですが、ちょっとした事だったのでGo言語で書く事にしました。
わりとどうこうなかったんですが、さすがのgo、ググラビリティが微妙であり、go言語入門にイケてる感じの記事がぱっとなかったのでメモ的な感じで残してみます。
基本的にPHPer向けです。
Helloworld
hello.go
package main import ("fmt") func main() { fmt.Println("Hello, world") }
LLっぽく実行するには(コンパイルと実行を同時にやるには)
go run hello.go
main関数から始まる、というのがC言語っぽくてなつかしいですね。
go runをつかうとスクリプト言語と似た感じになるので、とても楽で良いです。
環境設定
Goのライブラリは
みたいにして入れる事ができます。
そのときに、GOPATHがないとおこられるので、設定します。
これは自分のホームディレクトリ以下に適当に設定するとよいのではないでしょうか。
私は~/.goを作成して、以下のように.bash_profileに書きました。
export GOPATH="$HOME/.go/"
環境設定 エディタ
Go言語を良い感じにしてくれるエディタはなにがいいのかわからないんですけど、まあとりあえずvimは対応しています。
http://mattn.kaoriya.net/software/vim/20130531000559.htm
こちらを参考にして、vimの設定をしました。
:Fmt のオートフォーマット便利ですね、
echo
fmt.Print、またはfmt.Printlnをつかいます。Printlnは自動的に最後に改行いれてくれる、Perlでいうところのsayです。
上のHelloworldをみてください。
標準エラーSTDERRに出力したい場合には、Fprintlnをつかいます
//fmtとosをimportしておく必要があります。 fmt.Fprintln(os.Stderr, "Error”);
簡単な文字列操作
宣言は
str := "great string"
で宣言ができます。「:=」は右辺の型からよしなに左辺の型をきめて宣言してくれる感じですね。
連結は+演算子でできます。
str = str + "!!!" str += "???"
Substrは「str[1:2]」とかやります
fmt.Println("Hello, world"[7:]) // world fmt.Println("Hello, world"[3:5]) // lo fmt.Println("Hello, world"[0:1]) // H fmt.Println("Hello, world"[:4]) // Hell
文字の数を数えるのはlen関数を使います
fmt.Println(len("Hello, world")) // 12
単体でPrintlnに数値をいれるのは型キャストいりませんが、連結するならキャストが必要になります。
fmt.Println(10) // 10 fmt.Println("ten is "+strconv.Itoa(10)) // ten is 10
文字列を数字にキャストするにはAtoiをつかいます
num,_ := strconv.Atoi("15") fmt.Println(num+10) // 25
num,_ですが、これは返値が配列で返ってきて、第一引数には変換した数字、第二引数には成否が入ります。_を指定すると「捨てる」事になりますが、本来はここをみて「変換に成功できたか」をしらべる必要があります。
num3,err := strconv.Atoi("a10") if (err!=nil) { fmt.Println("cast error") }else{ fmt.Println(num3+10) // 10 (!?) }
ベターCっぽいですね。ただ、コード量がモリモリ増える!
ファイル読み込み
file_get_contentsみたいな感じでテキストファイルをロードするには以下のようなコードになります。
読み込むだけだとbyteの配列で返されるので、それをstringに変換しています。
stringsをimportしてください。
byte_array, err := ioutil.ReadFile("filename.txt") if err != nil { fmt.Println(err) exit } great_string := string(byte_array[:])
さらに、それを改行でくぎった配列にしたい、なんてときは以下のようになります。
string_array := strings.Split(great_string, "\n")
連想配列とforeachなど
Go言語には連想配列的なものでMapとスライスがあるっぽいんですけど、まあ、Mapをつかいました。上のコードからのつづきで、各行をキー名として配列をつくるなら以下のようになります。
string_map := map[string]bool{} for i, s := range string_array { if len(s) < 10 { continue } string_map[s] = true }
これはPHPでいえば以下のコードに相当します。
$string_map = []; foreach ($string_array as $i=>$s ){ if(strlen($s)<10){ continue; } $string_map[$s] = true; }
上に書いてありますが、連想配列に追加するのは
great_map[key_name] = value
となります。
いわゆるis_set()は以下のようにします
_, flag = great_map[key] if flag { // found ! return }
これはmapにアクセスすると、配列で受け取る事ができて、取得できた値をすてつつ、成功したかのフラグを見ています。
for
goのfor文は便利というか、色々な事ができるようになっていて、
// 普通のFor for i:=0; i<10; i++{ //... } // whileみたいなの flag = false for i==false { //... i = true } // foreachみたいなの for index, value := range great_array { //... }
全部forで書きます。
forでは当然continueがつかえますが、
for i<10 { //... if hoge { continue } }
phpでいうところのcontinue 2 をしたい場合には、forにlabelを定義する必要があります
label_name : for i <10 { for x < 10{ if hoge { continue label_name } } }
書くの面倒ですけど、何個抜けるか数えなくて良いのは良いですね。
文字列の配列の宣言
こんな風に宣言できます。
[...]の部分は配列の要素数を最初に指定せず、うしろの{〜}を数えてもらう感じです。勿論自分で指定もできます。
s := [...]string{"a", "b", "c", "d",}
乱数
timeとmath/randをimportしてください
rand.Seed(time.Now().UTC().UnixNano()) rand_num: = rand.Intn(9) // 0〜9の整数の乱数を取得
初期化は必須っぽいです。
当然ですけど、これは類推が可能なseedなので、このままかいたらダメです!!!
もっとちゃんとしたseedを使いましょう(こういうこと考えたくないんだけど!?(PHP脳))
参考になったURL
http://golang.jp/go_tutorial
http://golang.jp/effective_go
http://golang.jp/go_spec
http://golang.jp/go_for_cpp_programmers
http://golang.jp/pkg
「全部公式サイトじゃねーか!!!」公式ではなかったw