2013年12月31日火曜日

Dartのドキュメントを適当に翻訳し始めました。

2月のGDG中国のイベントのためにDartを調べているのですが、
平行して英語の勉強も”ある程度”しないといけないような気がしたので、
適当にDartのDocumentを翻訳することにしました。

とりあえず、翻訳した後の文章を見ても何となく分かるようなわからんような…。
(Golang Cafeとか、Blogでも書いたけど、「プログラミング言語 Go フレーズブック」の日本語がおかしいとか、読みにくいとか言ってたけど、翻訳者の苦労がよく分かる…。)

https://github.com/tyokoyama/dartdoc

私は、中学校の頃までは英語の授業があったけど、高校以降は、工業高校だったので、英語の授業が
高校からガクッと減ってるんですね。大学も工学部だったし、(正直その頃には英語に全く興味なかったし)週1回の講義が1年と、週1回の英会話の講義が1年…?だったかな。まあ、とにかくよくわからんのですよ。

特に、","が何個もつながった文章とか、わけがわからないし(今のところ、","で区切って短い文章で読み進める作戦)
あと、圧倒的に単語の意味を覚えてない。
それから、慣れない言語で文脈を読み取るのは今は難しい。

「あの時、しっかり勉強しておけば良かった」とまでは思わないけど、ある程度、単語も覚えていかないとだめだね。
ということで、ぼちぼちやっていこうかと思っています。

2013年12月30日月曜日

Golang Cafe #10を開催しました。

Golang Cafe #10を開催しました。

今回は、imageパッケージを使ってみる会ということで画像処理のコードを書いていました。
サンプルコードはGithubにpushしてありますので、ご興味があればごらんください。

今回提示したサンプルは

  1. png画像をjpegに変換する(単純に読みだして、そのまま書き出す)
  2. png画像に「#」を書き加えてpng画像を出力する。(#golangとしたかったけど時間が足りなかった)
基本的に画像を読み込む場合は、os.Open("ファイル名")でファイルを開きます。書き出す時は、os.Create("ファイル名")でファイルを作成した後、os.Fileのポインタを介して画像データを書き出します。

Goのimageパッケージは、画像のピクセル情報をimage.Imageインターフェイスを実装した構造体が管理しており、画像の形式(gif/jpeg/png)にかかわらず、Imageインターフェイスを介して画像が生成されるようになっています。ImageインターフェイスはRectangleの取得、color.Modelの取得、ピクセルの色を取得しかありません。
したがって、直接編集することができないようになっています。

画像を編集しようと思うとどうするか。というと、元画像を読み取り、いちいち画像データをコピーする必要があります。今回はRGBAにコピーしています。RGBAは一般的なRGBA(Aは透明度?)に対応した型です。
(以下はwritesample.goの抜粋です)
rect := img.Bounds()
rgba := image.NewRGBA(rect)
size := rect.Size()

// 元画像のコピー
for x := 0; x < size.X; x++ {
 for y := 0; y < size.Y; y++ {
  rgba.Set(x, y, img.At(x, y))
 }
}

// #golangとか書きたいけど、今は時間がない。
for i := 0; i < 10; i++ {
 rgba.Set(60, (10 + i), image.Black.At(0, 0))
 rgba.Set(65, (10 + i), image.Black.At(0, 0))
 rgba.Set((58 + i), 13, image.Black.At(0, 0))
 rgba.Set((58 + i), 16, image.Black.At(0, 0))
}

outRect := image.Rect(0, 0, rect.Max.X, rect.Max.Y)
outImage := rgba.SubImage(outRect)

RGBAだけでなく、Gray16や、RGBA64にはSet()が用意されており、ピクセルデータを上書きする事ができます。今回は黒で上書きしたので、定数で定義されている、image.Blackを利用しました。用意されているのは、黒と白だけのようなので、他の色は作るしかないです。
Goには、JavaとかC#などのように、「線を引く」「円を描く」「画像を描画する」というAPIが用意されていないので、自分でピクセルの上書き処理を書かないといけません。
(あってもいいと思うけど何でないの?)

しかも、画像として書き出すためには、image.Imageを作らないといけないので、出力用のRectangleを用意して、SubImage()で取り出すという事をしなければいけないという、ちょっと面倒な感じになっています。(ただ、データ構造として、interfaceになっていて、画像形式に依存したコードがそれぞれの処理で分離されているのは良い設計だと思う)

ということで、便利なライブラリがないかと探してみると、draw2dというライブラリが存在しています。後半はこれを使ったコードを書いて、動かすという流れになりました。
サンプルコードはwritesamplewithdraw2d.goを見て下さい。

draw2dを使う場合は、"code.google.com/p/draw2d/draw2d"をimportします。
ライブラリ自体を取得する場合は、go getコマンドで取得して下さい。

使い方は、image.NewRGBA()までは同じですが、その後、戻り値のimage.Imageをdraw2d.NewGraphicContext()の引数にして、GraphicContextを取得します。
GraphicContextには、DrawImage()も、LineTo()もありますから、それぞれのAPIを呼び出せば、画像が描けたり、線が引けたりします。
(それでも、少し不便な感じがしなくはないですが…)

文字も描画できますが、事前にTrueTypeFontを読み取らないといけません。
初期値が"../resource/font/"になっていて、しかも、freetype-goというライブラリに依存しているため、そちらのソースコードを編集するか、draw2d.SetFontFolder("font/")という感じで、事前にフォントのディレクトリを指定しておく必要があります。
しかも、それだけではまだダメで、任意のフォント(例えば、システムフォントなど)を読み出そうと思ったら、内部でチェックがかかっていて、ファイル名を勝手に生成するようになっているので、”MS ゴシック"とか、"ヒラギノ角ゴ"というようなフォントを指定してもそのまま使えないという残念な結果になりました。
(元々この辺は使えないのだろうか?)

ということで、imageパッケージ周りはまだまだライブラリを作る余地があり、標準に用意されても良さそうな感じはしました。来年の1.3以降のリリースに期待ですね。

さて、次回は、archiveパッケージを使ってみる会になる予定です。

2013年12月28日土曜日

2013年を振り返る。

2013年も、あと少しですね。

ここ数年は毎年やっていますが、2013年を振り返ってみたいと思います。
自分のBlogを見返してみると、2013年の目標を定めていました。

GDG中国の活動について

GDG中国の活動として、決まっていたのは、

1/13(日)第16回勉強会@岡山
1/19(土)GDG四国 徳島テクニカルセッション
2/9(土)第17回勉強会@広島

の3つで

その後、5回イベントを開催しました。
4/13(土)第18回勉強会@岡山
6/22(土)第19回勉強会@岡山
6/29(土)第20回勉強会@福山
9/7(土)第21回勉強会@岡山
10/12(土)第22回勉強会@岡山

他にも、
5/25(土)、26(日)Devfest Japan 2013
6/8(土)htmldayへの参加

あとは、講師として
7/27(土)Google Apps Script勉強会
9/28(土)Go言語勉強会

そして、Golang Cafeの主催が10回。
講演回数などを確認していると、結構やってるなと思ったり思わなかったり。
AngularJS:3回
Google Apps Script:2回
Android:2回
Go:1回+Golang Cafe

回数からすると、今年はAngularJSを押してたのかな?と思ったりしています。
今は、Goを押していますけど、Googleのどのプロダクトも便利なもので、
使ってくれる人が増えるといいなーと思っています。

しかし、一時期、発表の質が落ちてしまって、参加者の方には非常に迷惑をおかけしてしまった部分も会ったのかなと思っていますので、今後はしっかり準備をしてから臨みたいと思います。

コミュニティとしては、スタッフが転職していなくなったり、プライベートが忙しくなったりと、スタッフがズタボロな状態なので、これを何とかしないとダメなのと、
いつも使わせて頂いていた会場が閉鎖になり、広島でのイベント開催が難しくなった事もあって、どうしても縮小傾向で考えないとダメなのかもしれない。
ただ、その前にもう少しスタッフにお願いするようにしてみようとも思ってたりしています。

それから、GDG中国で今後やってみたいなと思っているテーマは、

  • Google App Engineの言語はどれがいいのか?
  • Android 4.4の新機能について。
  • Dart(これは2/11(火祝)にやります)
  • AngularJSを岡山で。
  • Google Apps関係
    • 各種APIを叩くとか、サービスの連携とかをネタに。
  • Maps関係
と、考えています。発表が全て私である必要はないと思うのでもう少し、いろんな方に頼っていきたいと思います。

仕事関係

2013年は公務員になるという事があったので、目標を達成する事ができませんでしたが(というか、何もかもが変わってしまった)その振り返りをしてみたいと思います。
  1. 早朝の配達のバイト
  2. 専門学校の非常勤講師
  3. Google Appsのアドバイザー→データの移行プログラム(βバージョン)の作成案件(?)
  4. Androidアプリケーション/Chrome Extension/Google App Engineのアプリケーション開発
  5. その他突発の社会人講師とか。

3月までは、上記の仕事をしていました。特に専門学校の講師に関しては、一度やることになっていたのに急遽キャンセルをしてしまったというのが、申し訳なかったと思っています。
今思うと、「よくやっていたな」とも思えますし、「第二の人生」と思って活動してきました。
とはいえ、Androidの講師や、テクニカルレビューアを担当させていただき、それなりに、これまでと同様の活動ができたことにも感謝しないといけないと思います。

と、いうものの、Androidアプリケーション「今日のアドバイス」を作りましたし、
iPadとiPhoneで通信させるWebアプリ(実際にはAndroidも使える)を学校の仕事で作りました。その他にもExcel VBAマクロを駆使したものも幾つか…。

ということで、IT関連の事もある程度はできたかなと思っています。

技術関係

  1. Google Apps(無料版)をしっかり使う
  2. Google+も主力にする
  3. Go
  4. AngularJS(HTML5 + CSSも)
  5. blogをしっかり書く
  6. 書籍も読む
  7. なんか執筆(?)
ということを目標に掲げていましたが、執筆は立場上不可能になってしまったのでダメでしたが、1と7以外はしっかりできたかな?と思ったり思わなかったりしています。

実際、Pure + AngularJS + GAE/Gとか、Bootstrap + AngularJS + GAE/Gという構成でWebアプリケーションを作ってみましたし、本業の方には敵いませんが、ある程度勉強できたと思います。G+も主力になって、非常に便利に使っていますし、いい事づくめですね。書籍もしっかり読んで、Blogに感想を書き残すということもできたので良かったのかなと。(ただ、数がそんなに多くない気もしなくはない)

ただ、Google Appsを有効利用できなかった(ほぼ塩漬け状態だった)のと、ドメインをしっかり取り直そうかなとか思っていたりするので、いろいろ整理してから、来年に臨みたいですね。

ということで、今年もいろいろな方にお世話になりました。良いお年をお迎えください。
来年の目標はまた来年に投稿しようと思います。

はじめてのBootstrapを読みました。

はじめてのBootstrapを読みました。
Twitter Bootstrapの使い方が知りたかったので購入してみました。
全5章のうち、最後の5章は実際にWebサイトを構築するという章だったので、
また時間がある時に読むことにして今回はパスしています。

2章からの基本的なCSSを適用するというところで、ひと通りのUIを体験し、
3章で用意されているコンポーネントが紹介されます。
ここまでの内容だけでも、それなりにモバイルアプリケーションが作れました。
(生徒に文句を言われることもなく…。)

レスポンシブデザインについての記述もしっかりされており、読んで、サンプルを入力するだけでは、難しいかもしれませんが、実際に作る段階になれば、おもしろい事ができるようになっていると思います。

4章からはJavaScript APIを利用した、動きがあるもので、Webアプリケーションに導入するには非常に便利なものが紹介されていました。

ただ、(書籍を読んだからかもしれませんが)本家サイトにある、解説に書かれている事が書籍になったという感じにも受け取れるので、慣れた人にはこの書籍は向かないと思います。また、dotinstallなどにも解説があるそうなので、そちらを見たことがある方は、購入の前に立ち読みをしてみた方がいいかもしれません。

ということで、個人的には非常に有意義なものでした。
ぜひ初心者の方は、読んでみてください。

2013年12月23日月曜日

Golang Cafe #9を開催しました。

Golang Cafe #9を開催しました。

今回は、「Go言語でデザインパターン」ということで、結城浩さんの書籍「Java言語で学ぶデザインパターン入門 マルチスレッド編」を、2月頃にGoで書いたものがあったので、それを元に進めてみました。
githubのリポジトリにタイトルのままのディレクトリが作られているのでそちらをごらんください。

最初の「Single Threaded Execution」では、本来は、排他制御を行わないと、変数の値が正しく読み取れない(他のスレッドでの変更が中途半端に反映された)状態が発生して、「Broken」という出力がある想定だったのですが、Go on Mac OSXだと、何もしなくても、全く不整合が発生せず、その時の状況を忘れてしまっていたので、3人でハマってしまいました。(Windowsでは、不整合が発生したので排他制御を入れなければいけなかったが、Ubuntuでは全く発生しなかった)
恐らく、コンパイル時に最適化されてしまったのかな?と後になって考えるところです。
Goroutineの切り替わりが問題か?と思って、runtime.GOMAXPROCS(3)とかも適用してみたのですが、全く不整合が発生しませんでした。
該当コードはこちらです。(channelで排他制御のコードがありますが、全く無意味 http://play.golang.org/p/gz21HM20kv

本来、ここで言いたかった事は、「しっかり排他制御を行って、同時にアクセスできるのは1つのスレッドのみ」ということを実現しましょう。ということでした。

次の「Immutable」は、複数のスレッドで実行しても、値を変更するAPIを用意しなければ、変更したくても変更できないというパターンです。
特に問題が発生しなかったので素通りしました。

最後に、「Guarded Suspention」はchannelはスレッドの終わりを待つだけのものなので、特に注目するところではないのですが、今回は、sync.condを使って排他制御を行っています。(これが正しいかどうかは別として、書籍のコードと同じような事をしようと思うと恐らくこれだろうと思っています)
理由としては、C#でいうところの、Monitor.Wait()とMonitor.Pulse()を実現する方法がChannelでは不可能だからです。(でも、実際には同じような事はバッファリングすればできる…か?)
プログラムの内容としては、ClientスレッドがQueueにPutするまで、Serverスレッドは待ち続ける。という内容になっていて、スレッドの動作はバラバラですから、Queueにデータがある間はsync.cond.L.Lock()でロックし、値を取り出し、キューから削除してUnlock()しますが、データが無くなった時には、sync.cond.L.Wait()でキューにデータがセットされるのを待ちます。
Clientスレッドでは、キューにデータをセットしたら、sync.cond.L.Signal()を呼び出して、サーバ側にデータが入った事を伝えています。(その後は、CPUが勝手にスレッドを動かすはずなので、どのスレッドでもどうぞ。ということで)

ここで、問題になったのが、init()の呼び出しについて。
init()はパッケージが読み込まれた時に、1度だけ実行される特殊な関数ですが、構造体のメソッドとしてinit()を定義していても呼び出されるのか?という話になりました。
そこで、最初は「呼び出される」(static{}と同じ動き)と言っていたのですが、ドキュメントにそのような記載はないし、よくよくコードを確認すると、main()に呼び出しがあったので、メソッドにした場合は、呼び出される事はありません。(コメントアウトしてみると、panicになりました)

というところで、2時間が経過したので、ここまでとなりました。

次回は、12/29(日)に10回目を行います。
テーマは「imageパッケージと戯れる」にする予定です。



2013年12月16日月曜日

Golang Cafeを開いた結果

この記事は、Go Advent Calendar 2013の16日目の記事です。
内容が技術な感じではないので、Qiitaへの投稿は控えました。

2013/10/27(日)から、毎週日曜日の夜に、「Golang Cafe」というGo言語をみっちりやる会をやることにしました。
東京では、Go研というイベントが開催されており、標準パッケージを読み進めるスタイルになっています。(目的は標準パッケージを読み、Goでの設計方法を研究する)
これを自分でもやってみようと思ったのがきっかけです。

本来は、私自身が、Go言語を使うことが少なくなってしまったのと、転職したので、職業上コードを書く機会がかなり減ってしまったので、強制的に書く時間を作ろうと思って、イベントをやることにしました。毎回、「一人でもやります」と書いているものの、一人になったことはなく、毎週2人の猛者が参加して頂いています。

ということで、3人のメンバーで毎週、勉強会をやっています。

Golang Cafeのこれまでのテーマを挙げます。

  1. How to write Go Codeの内容
  2. encoding/jsonパッケージのソースコードを読む
  3. GoroutinesとChannelsで並列処理入門
  4. database/sqlパッケージを触る
  5. osパッケージを触る
  6. text/templateパッケージを使う
  7. Goのプレゼンのプレお披露目/Go1.2の概要
  8. プレGo年会
  9. 既存言語のデザインパターンをGoで書いたら?(12/22開催予定)
という流れですすめてきました。

結果、自分自身の知識が深められた。(職業上、仕事には生かせられないけどw)
参加者のレベルがあがった。(今後、GDG中国の戦力に…)

実際、当初の目的からは活動内容が変わってきていますが、特に問題ないと思っています。ただ、会のなかで、「他の言語で書くと…」という話題が出てくる事が多いので、
標準パッケージや、実際のGoのプロダクトを読みつつ、設計を研究していく必要はありそうです。

ただ、標準パッケージの読み方にもコツがあって、reflectパッケージから読み始めた方が、色々有利な事が多いと思いました。
理由は#2の時にencoding/jsonパッケージを読もうとしましたが、中でreflectパッケージがかなり使われていて、reflectパッケージを読んでおかないとencoding/jsonパッケージに集中できないという状況が発生したからです。
ということから、reflectパッケージは早めに読んでおく方が良さそうです。

それから、osパッケージは中でsyscallパッケージを使っているので、syscallパッケージを読み進めたほうがいいですが、Windows版に関しては中身が「return -1」が連発しているという、いわゆる「サポート外」のコードが散見されますので、Windows版でソースコードを読み進めるのは現時点では、おすすめしません。
(今後も改善の余地があるんだろうか?OSの仕組みから違うような…?)

といった所で、これまでに得た事をつらつらと書いてみました。

※#golangや#gdgchugokuでTwitterに投稿するので、気が向いたら反応してください。

Golang Cafe #8を開催しました。

Golang Cafe #8を開催しました。

今回は、東京で行われるGo年会に合わせて、岡山でも非公式でやってしまおうということで、勝手に「プレGo年会」というテーマで進めてみました。
(Go年会参加者は、参考にしてねw)

で、開催中にGo言語フレーズブックを開こうと思って、かばんを見ると…、かばんの中に書籍がないという事実が発覚して(日中に教員免許更新講習を受けてきた時に会場に置き忘れた?)ということで、書籍をその場でAmazonで購入するという事件がありました…。
正直、ショックです。。
が、正誤表が、以前の私の指摘した部分だけでなく、だいぶ増えていて、改めてみると驚きました。と同時に、コードを書いて動きをみていないなと思いました。
当時のBlog記事も見直しましたが、今日の発言と微妙な食い違いがありましたので
改めて読み進めようと思いました。

さて、内容は、質問の回答と今年1年のGoの振り返り、来年のGoの動向(というか希望?)について、雑談を交えて話をしてきました。

  1. 質問の回答
    1. 配列型引数の関数は呼び出し元に影響を与えるか?
      1. 呼び出し元に影響を与えない。(引数の値は編集されない)
      2. 引数がスライスの場合は、呼び出し元にも影響が出る。(編集される)
        1. ただし、引数が配列型の関数にスライスを指定するとコンパイルエラーになる。
        2. 基本的に実体はコピーされて、ポインタ、スライスなどは影響する。
      3. ソースコードはgithubをごらんください。
    2. Goにメソッドのオーバーロードは無いのか?
      1. ない。(コンパイルエラーになる)
      2. Goにオーバーロードはなぜないのか?
  2. 今年1年の振り返り
    1. Go1.1→Go1.2に
      1. Go1 and the Future of Go Programs」によると、1.2.1、1.3、1.4の記述があるから、今後もバージョンアップしそうだね。
      2. そういえば、AngularJSも1.3がでたとかなんとか…。リリースは早いなー。(1:03追記:リリースではなく、対応方針が発表されたの間違いでした。)
    2. Go関係のコミュニティ、イベントが増えた。
      1. 個人的には全く参加できてないけど、いつかは参加してみたいですね。
      2. 今後も増えてくるんじゃないだろうか。
    3. Lite IDE
      1. Ver18で止まっている…?
      2. Golang IDE Ver20がリリースされている。
        1. アイコンが同じ。
        2. どういうこと?
      3. GolangJPのG+コミュニティにあまり投稿がない。
        1. +Ryuji Iwataさんがんばって!
        2. 試しにGolangJPにGolang Cafeの告知流そうか。
      4. エディタ
        1. Sublime Text
        2. Vim
      5. 高級言語を使っているとGoは使い勝手が悪いんじゃないか?
        1. 速度を考えると実装されなさそうな機能が多い?
          1. Genericsとか、演算子のオーバーロードとか。
            1. Goにオーバーロードはなぜないのか?
      6. Go言語でできることはなんだろう?
        1. HTMLUnitがあるとうれしい!
        2. 既存のアプリケーションをGoで置き換えたい…。
          1. バッチ処理の部分ならいける!?
          2. 並列性を活かせるもの
          3. 1つの処理でも複数のGoroutineで回して最後に終わったGoroutineの後で、全てを出力する…。みたいな。
        3. GoでHTTPサーバとか?
          1. Apacheをリバースプロキシで使うとかして…。
      7. Goの互換性
        1. Ver1.0から互換性を保つということを謳っているので、バージョンアップしても大丈夫なはず!
        2. Go1互換のガイドラインに沿ってSub repositoryに分割されるのでは?
        3. よって、Ver1.0のコードをVer1.2のコンパイラでコンパイルしても落ちることはないはず。当然、挙動も変わらない。
      8. OAuth2ライブラリなどもある。
        1. https://code.google.com/p/goauth2/
      9. リコーのGoのプログラマ採用がでてきた!
        1. https://www.ricoh-careers.com/job.phtml?job_code=302
  3. 来年のGoの動向(予想)
    1. GAE/GのExperimentalが外れて欲しい!
    2. Goの案件が出てきて欲しい。
      1. Cのプログラムを置き換えるとか…。
        1. COBOLの案件も…。
          1. ファイル出力系は置き換えられそう?
    3. プロダクトへの導入
      1. リコーは採用があるくらいだから、そのうちリリースがありそう?
      2. GoogleはどんどんC/C++のコードをGoに置き換えるということが発表されているので、日本の企業もだんだんとバックエンドがGoで作られるという日がくるのでは?大規模なものの方が向いてそうな気がする。

といった所で、今年のGo言語の様子はいろいろありました。来年はGoが実戦投入されることを祈っています。というか、投入されてどういう結果になったかの報告が聞けそうです。

あとは、比較的近く、いつもお世話になっている+Yasutaka KawamotoさんともGolang Cafeやってみたいですね!

では、次回の
Golang Cafe #9は2013年最後の回になると思います。
次回は、私が個人的に進めていた、「Go言語でデザインパターン」の話をしてみることにします。

2013年12月11日水曜日

Golang Cafe #7を開催しました。

Golang Cafe #7を開催しました。

今回は、+Takanobu Haginoさんの疑問に答えた後、+Ryuji Iwataさんの発表資料のお披露目があったので見させて頂いたのと、Go1.2の変更点を幾つか紹介した流れとなりました。

+Takanobu Haginoさんの疑問
  1. C#のdecimalに対応するものは何か?
  2. 演算子のオーバーロードなどの機能は?
  3. 変数の型が何かを知る方法は?
私が知るかぎりでは、2は、Goには存在しません。理由は速度に影響があるのか、複雑になるからなのかはわかりませんが…。

1は、math.big.Intとか、math.big.Ratを利用するしかありませんが、これはJavaのBigDecimalのようにメソッドを呼び出さないと計算ができないので少々面倒なのですが、この問題を解決しているのがC#のdecimal型なんですよね…。

3は、Go1.2からfmtパッケージの書式が増えて、%Tが指定できるようになっています。これを使えば型の名前を出力する事ができます。Debugなどで使えば便利だと思います。プログラムで判定するなどしたい場合は、switch文の中で、変数名.(type)の記述をすることで判定が可能です。型を実際に取得する場合はreflectパッケージを利用する歯科なさそうです。

次に、+Ryuji Iwataさんのプレゼンですが…発表当日をお楽しみに!

最後に私からGo1.2の変更点について、nilの扱いとThree-Index-Slices、fmtパッケージの変更点について紹介しました。

最初のnilの扱いについて。

package main

import (
        "fmt"
)

type T struct {
        Field1 int32
        Field2 int32
}

type T2 struct {
        X [1<<24]byte
        Field int32
}

func main() {
        var x *T
        p1 := &x.Field1
        p2 := &x.Field2
        var x2 *T2
        p3 := &x2.Field

        fmt.Println(x2.X[0])        
        fmt.Println(p1, p2, p3)
}

上記のようにnilポインタの変数のメンバを参照した時に1.1の時はアクセスできていたようなのですが、1.2からはpanicになるように変更されました。ただ、実際に動かしてみるとどちらもpanicになったような…。
現時点では、nilポインタアクセスさせるということがないので、いまいちわかりませんでした。変な事はしないということが重要ですね。

次に、

        var arr [10]int

        for i := 0; i < len(arr); i++ {
                arr[i] = i + 1
        }

        slice := arr[2:4:7]
        //slice := arr[2:4:4]

        var slice2 []int = slice
        for i := 0; i < 5; i++ {
                slice2 = append(slice2, 11 + i)
        }

        fmt.Println(slice, len(slice), cap(slice), arr, slice2, cap(arr))

上記のように、sliceを取得する時に、3つ目の値を指定することで、容量を取得する事ができるようになりました。実際にappendしていくと、参照元のarrの値が容量いっぱいまで更新されるようになります。また、確保される容量は、7-2=5となります。7個確保されるわけではなく、2番目から7番目までの容量という意味で捉えるといいでしょう。
上記の結果だと、1 2 3 4 11 12 13 8 9 0という配列になります。slice側は容量よりも大きくなっても値は保持されます。
sliceなので、元の配列arrの容量には影響は与えませんでした。値のみ影響されるようです。
以前は、容量の指定がなかったので、まちがって編集すると元もすべて影響をうけていましたが、容量指定のおかげで、少なくとも、容量よりも大きな添字の値は守られるようになっています。

fmtパッケージの変更点は、型名が出力される%Tの他に、出力する引数の番号を指定できるようになりました。%[1]dという指定をします。開始番号は1です。
%[3]d %d %dとすると、2番目の省略した所は、4番目を参照しようとします。したがって、省略したら指定した番号の次を出力という動きをしています。

次回のGolang Cafe #8は、今年のGo言語の振り返りと来年以降の動向を聞いてみようと思います。4年もたった言語ですからそろそろ大きな飛躍があると思いますので…。



2013年12月5日木曜日

Golang Cafe #6を開催しました。

Golang Cafe #6を開催しました。

今回のテーマはtext/templateパッケージの使い方が主なテーマになりました。

リポジトリはgithubにありますので、作成したコードはそちらを参照して下さい。

始まる前に、「Goで複数行にわたって記述する方法」について話題になったので、
そのことを調べました。
Goの場合は、明示的に「次の行に続く」事を書いておけば大丈夫なようです。
以下の例だと、正しく動きますが、
 str :=  "Hello" +
 " World!" +
 " Hoge!"

 n := Name("hoge")

 n.
  Print()

以下の例だとコンパイルエラーになります。
 str :=  "Hello"
 + " World!"
 + " Hoge!"

 n := Name("hoge")

 n
 .Print()

最初に簡単な使い方を紹介しました。

templateに任意の値を追加する時は、{{.Name}}というようにテンプレートを追加します。
先頭の"."はtemplate.Execute()で指定した引数のオブジェクトを示しています。
したがって、構造体を指定した場合は、メンバを指定することも可能です。標準の型の変数を指定した場合は"."と指定することで値を表示させる事が可能になります。

次に{{range $index, $element := .}}{{end}}とすると、rangeキーワードを使ったfor文と同じことを実現できます。先頭に$が付いたものはテンプレート内変数でrange以外でも使うことができます。
要素が0件だった時に、0件の処理をしたい場合は{{else}}を記述しておくと、else側が処理されるようになります。

{{if .Flag}}{{else}}{{end}}などとすると、テンプレート内での条件分岐が実現できます。
.Flagは判定条件です。

{{len .}}とすると、引数で渡された値の長さが取得できます。len()を呼び出しているのと同じ意味になります。これを使って、「取得件数:XX件」という事が実現できます。

templateはファイルに記述しておき、ファイルの内容から生成することも可能になっています。
t := template.Must(template.ParseFiles("sample.txt"))
とすると、sample.txtに書かれたテンプレートを読み取り、正しく記述されていればTemplateオブジェクトが取得されます。しかし、記述に誤りがある時は、panicになります。template.Must()はtemplateが必ず生成できることをチェックする関数です。
テンプレートが動的に変わるなど、正誤があいまいな時はMust()は使わないほうがいいでしょう。

また、template.ParseFiles()は複数のファイルを指定して一括で読み込めるので、
以下のように、複数のファイルを読み込ませても構いません。
t := template.Must(template.ParseFiles("sample.txt", "sample2.txt"))

テンプレートには名前をつけるようになっていて、template.ParseFiles()で読み込ませた時のテンプレート名はファイル名がそのまま付きます。
特定のテンプレートを取得したい時は、t.Lookup("sample2.txt")などとテンプレート名を指定してオブジェクトを取得します。

特定のテンプレートを指定してテキストを出力する時は、
err := t.ExecuteTemplate(os.Stdout, "sample2.txt", members)
のように、ExecuteTemplate()を呼び出すと可能です。2番目の引数がテンプレートの名前です。

次回のGolang Cafe#7は先週(今週?)リリースされたGo1.2の変更点について扱う予定です。