YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

Go Conference 2013 autumnを開催しました #gocon

はじめに

こんにちは、Go界のジャック・ニコルソンです。連休最終日の10/14に日本マイクロソフトさんの品川オフィスをお借りしてGo Conference 2013 autumnを開催してきました。

新幹線を使って参加された方もいて、大変うれしかったです。次回はまた半年後の春頃に開催したいと思っています。GoConでは絶賛発表者を募集しておりますので「何か作った」「突っ込んで調べてみた」という方がいたらご連絡ください。また次回もLTをしようと思うので、こちらはもっと気軽な感じで参加してみてください。

発表者スライド

LT

プレゼン

Gopher in the Cloud」という話をしてきた

クラウドとタイトルに付いていますが、GoをサポートしているPaaSの話と、Build Constraintの話をしてきました。

Go言語はその立ち位置からしてグローバルで見てもインフラ系のエンジニアにすごく人気で、PaaS/IaaSベンダーのエンジニアが多くコミットしているイメージがあります。しかしながら、そういうエンジニアが彼らのインフラ上でGoのアプリケーションを容易に動かせるように、非公式とはいえハックしてくれていて、ほぼ準公式に動作するものとして公開されています。

GoはC++/Javaがカバーしていたミドルウェア系のソフトウェアを書くだけでなく、LL系で実装したAPIやWebサービスを高速化する事例でも使われ始めていて、実際にAndrewのキーノートでも紹介されているように、標準パッケージのみでもある程度のものであればWebアプリケーションを作れるようになっています。まずは多くの人に試してもらいたいとおもったので、プレゼン前半では3rd partyのPaaSをいくつか紹介しています。

後半ではBuild Constraintsという若干応用的な内容を紹介しました。Build Constraintsを用いることで、複数の環境で異なるソースを用いてビルドを行うことが出来、ネイティブコードを吐くGoの柔軟性をさらに高めることが可能となります。 肝心なのはこれがソース内のコメントのみで制御される点で、ビルドファイル無しでビルドができるというGoの設計が反映されています。

Tシャツ販売

@nuki_ponさんがGoConオリジナルTシャツとスタンダードなGopher Tシャツの販売を始めました。コミュニティ発Tシャツ熱い!!GoCon Tシャツは10/21までの1週間限定販売だそうです。

謝辞

会場提供をしてくださったマイクロソフトの藤山さん、ありがとうございました。再度スポンサータイム。

また運営を手伝ってくださったみなさん、ありがとうございました。 > @Jxck_、@tenntenn、@nuki_pon、id:futoase、@es_kap、@ikasamt、@manji0112

感想ブログエントリなど

関連エントリ

引越し備忘録

はじめに

こんにちは、Go界のジェット・リーです。10年間北区に住んできたのですが、新しい場所に住んでみたいという気持ちと、通勤時間を減らしたいという気持ちが強くなったので、勢いで先々月引越をしてみました。その際色々とやることがあって、想定していたよりやることがあったので、今後のために残しておきます。

家を借りたくなったら

家を借りたくなったら

引越し準備 (2013年6月中旬〜7月末)

部屋探し (2013年6月中旬〜7月中旬)

足で稼ぐのは厳しいので部屋探しサイトを活用した。いくつか選択肢があった中で、suumoで検索条件をマイリスト化して、新着物件をメールを受け取るのが一番性にあっていた。 結局知り合った仲介業者から送付されてきた物件も合わせて、間取り図は200枚近くは見た気がする。その中から選んで内見は7件ほどおこない、最終的に2つの候補から現物件を選んだ。

契約 (2013年7月中旬〜7月下旬)

仲介会社、管理会社各々に対して手数料および各種料金の支払いを行った。物件の管理会社がわかっていたため、直接管理会社に掛けあっても良かったが、時間がもったいなかったため仲介業者に交渉や諸項目の確認を任せた。 交渉に関しては家賃が下がったあとの交渉だったため、金額面では特に割引はなかったが、入居日に関してかなり融通を利かせてもらった。これだけでも半月分の家賃は浮いた。

引越し作業 (2013年7月下旬〜8月末)

インフラ系停止・開始連絡

東京電力が運営している「引越れんらく帳」が大変有用。電気・ガス・水道の停止・開始の連絡をウェブ経由で一発でできる。それだけでなく、ここにまとめてあるような諸々の民間サービスに対して連絡を行ったかのチェックリストも作成できるため、まずはここでアカウントを作るのが良い。

引越し業者選定

なんか楽そうだったので「引越し侍」を使ったら、電話がじゃんじゃんかかりまくってきて最悪だった。あと引越し侍の電話オペレータもなんか全然応対ができない感じの人で全然話が噛み合わなかったのでめんどくさかった。二度と使わないし、使うこともおすすめしない。

大手引っ越し業者は、テレアポの人がやたらピッチが高い声色で独特の日本語を使ってるし電話かけるたびに同じことを3回も4回も言わなきゃいけないし、業務中でもガンガン電話かけてくるし、メールでの応対しないっていうし、引越し業界は終わってると思ったし、こんな人件費に引越し費用がかかってると思ったら頭にきた。TVCM流す前に業務改善しろ。具体的には「アリさんマークの引越社」「サカイ引越センター」が最も電話連絡が煩わしかった。

そんななかで結局利用した「フクフク引越センター」はまともな対応で、メールでの応対もしてくれ、値段も良心的だったので良かった。

荷造り (2013年7月下旬〜8月中旬)

契約が決まるまでは何もしたくなかったので、逆に契約が決まってからはバタバタしてしまった。結局次のような量になった。

  • 大箱6個
  • 中箱3個
  • 小箱5個
  • 1.5Lペットボトル半ダース用箱5個
  • 衣装ケース6つ
  • 140Lバッグ1つ
  • ギター1本
  • ベース1本
  • ベースアンプ1個
  • デスクトップマシン3つ
  • こたつ
  • 姿見
  • シングルベッドフレーム+マットレス
  • 掛け布団、毛布、ブランケット、枕
  • アーロンチェア1脚
  • 24inchモニタ、19inchモニタ各1つ
  • 自転車1台

粗大ごみ廃棄 (2013年8月上旬)

自分の自治体では粗大ごみを捨てる場合は事前に廃棄日の予約と、廃棄物に応じた粗大ごみチケットを購入しておかなければならなかった。

荷解き (2013年8月中旬〜8月末)

引っ越し当日にダンボールは8割方片付けてしまったし、ベッドも棚も組み上げてしまったので特に問題はなかった。

引越し事後処理

転居元清掃 (2013年8月中旬)

転居元が転居先からそこまで遠くないため(電車で30分程度)、転居先への荷物搬入完了後に転居元の清掃を行った。 基本は掃除機でホコリを吸い取る作業ばかりだったが、床にクッション材として使っていたゴム板のカスがへばりついていたのを取る作業が厄介だった。 歯ブラシとマジックリンで綺麗に落ちた。歯ブラシとても便利。

ゴミが「可燃ごみ」「不燃ごみ」「資源ごみ」それぞれあったので、転居後にも各ゴミを転居元自治体のゴミ収集日に合わせて出さなければいけないのは不便。 ゴミ集積所がある集合住宅であればこういう心配がなくて正直羨ましい。

オフライン手続き

行政

転出届 (2013年8月中旬)

転居先の自治体で転入届を提出するためには、転居元で転出届を出して、転出証明書を受け取る必要がある。 転居元は北区なので、北区の転出証明書を受け取る。

転入届・印鑑登録 (2013年8月中旬)

転出証明書を受け取ったあとに、転居先で転入届を行った。渋谷区はヒカリエに区民サービスセンターがあり、土曜日も半日対応してくれているのでとても助かる。

印鑑登録は転入届を行う際に窓口で申請書類をもらって引き続き行うことが出来る。

転居・転送サービス(2013年7月末)

当面の郵便物が転居先に来るように郵便局に申請する必要がある。最近はネットでも登録ができるらしく便利。自分の場合はオフィスのそばに郵便局があるので、昼休みに提出した。事前に登録できるので、転居の2週間以上前でも申請だけしておいた。

運転免許証住所変更(2013年9月中旬)

なぜかこれだけだらだらと先送りにしてしまった。手続き自体は非常に簡単で、住民票、公共料金の領収書/請求書などで新住所と氏名の記載があるものなどがあれば手続き可能。自分はNTTの料金請求書で変更手続きを行った。時間にして10分程度。

個人

インターネット回線&プロバイダ契約 (2013年8月上旬)

家のインターネット回線はFLETSで、プロバイダがOCNというNTTにおんぶにだっこな感じだが、116に電話するだけで回線の移転手続きが終わったのは大変良かった。ただ転居先がフレッツ光のマンションタイプに入っておらず、ファミリータイプに加入して最悪穴空け工事をする必要があると言われたので、工事当日に確認してもらい穴空け工事が必要になった場合には解約するということで回線移設の連絡をした。

当日は配電盤部分から光回線を引きこもうとしたが、集合住宅の共有部を通さざるを得ない状況となり、大家から認められなかったため、外からエアコンダクト経由で通した。こちらに関しては無駄な心配をすることになるため、契約時に管理会社に「光回線の引き込み可能の確認が取れるまでは契約しない」という条件を盛り込んでも良かったかもしれない。

クレジットカード住所変更届け(2013年9月上旬)

利用しているクレジットカード会社によってまちまちだが、オンラインで変更できるものは非常に楽で助かった。トラップだったのはTカードは、Tサイト、Tカードそのもの、クレジットカード機能それぞれに対して住所変更届を行わなければいけなかったことぐらい。

銀行口座住所変更(2013年9月末)

これも利用している銀行によるが、メガバンクはオンラインで変更できるので非常に楽。少なくとも確認しただけで次の銀行はオンラインで変更可能だった。

ただしシティバンクに関してはウェブでの変更にあたってワンタイムパスワード(OTP)を利用する必要があり、OTP利用開始にあたって郵送される通知書を待つ時間が3営業日ほど必要となる。

保険契約住所変更届け(2013年8月下旬)

契約していた保険会社に住所変更届を行う必要がある。こちらも契約している保険会社によって変わる。自分の場合は電話一本で済ませられたので助かったものの、自分のタイミングで変更できるWebシステムがないのは微妙。 このへんはライフネット生命みたいなオンラインが主の保険会社だと違うのだろう。

会社

住居変更 (2013年8月下旬)

住民税や年金の納付先が変わるので、会社側に伝える必要がある。人事に伝えて完了。

おわりに

振り返ってみると色々とやることがありましたが、こうして作業を洗い出してみると結構並行してできるものも多く、いつになるかわからないけれど、次回の引越しはより一層スムーズに出来そうです。

XPath使うならxmlpathパッケージ

はじめに

こんにちは、Go界の大杉漣です。いま、辻堂で合宿をしています。

xmlpathパッケージ

GoでHTMLをパースしてごにょごにょしたいというときはgoqueryを使うことが多いですが、個人的にはあのコールバック書きまくるスタイルが好きではなく「そこまでjQueryの真似しなくてもいいだろ」と思っていました。

またPythonで割とlxmlを使っていたこともあって、XPathを使うのが好きだったのでGoにも同様のXPathを扱えるパッケージがないかと探してみたらCanonical製のxmlpathというパッケージがありました。

使い方

めちゃくちゃ楽。ドキュメントにあるサンプルだとちょっと実用性がないので、もう少し実用性のある例。

resp, _ := http.Get("http://sample.com/content")
defer resp.Body.Close()

path := xmlpath.MustCompile(`//a[@rel='bookmark']/@href`)
root, _ := xmlpath.ParseHTML(resp.Body) // HTML扱うならParse()ではなくParseHTML()

iter := path.Iter(root)
var links []string
for iter.Next() { // イテレータ回せ
    n := iter.Node()
    links = append(links, n.String())
}
return links

これで sample.com/content のページ内にあるaタグで、rel属性が "bookmark" となっているもののhref属性を全部取得できます。便利。

(翻訳)英語は私にとって15年にわたって悩みの種です

はじめに

Redisの開発者である@antirezが一昨日投稿したブログポストにとても共感したので翻訳しました。

世界一わかりやすい英文法の授業

世界一わかりやすい英文法の授業

僕が@antirezの文章を翻訳するのは今回が初めてではありません。RedisのドキュメントをまだRedisがバージョン2.0になったばかりの頃に日本語訳したのが最初でした。Redisドキュメント日本語化をしていた当時は翻訳しながら「ドキュメントが整っているなぁ」と感じたと同時に「独特の英語を使うなあ」という印象を受けました。その当時は彼が英語に苦労していた過去のことなど知らなかったので、こうして本エントリを読んで振り返ってみると、苦労しながら英語のドキュメントを整えた彼の労力に本当に頭が下がります。

感じることはたくさんありますが、まずは彼のエントリを読んでみてください。

英語は私にとって15年にわたって悩みの種です

ポール・グレアムがニュースサイトやソフトウェア開発者が注目している彼のブログの中で、IT関連職従事者に必要とされる英語という言語について、非常に重要な問題提起をしました。(追記:こちらも id:yomoyomo の日本語訳があります! c.f. 創業者の訛り) このエントリは「外国訛り」について触れたことやそもそもインターネット上には大げさに反応したがる人がたくさんいることから大いに賛否両論でましたが、その点は先ほど言った問題提起の中では面白くない議題なので、ここでは省略します。 重要な点は、通常誰も「英語問題」について話さない、というところです。そして私はいつもこの点で孤独に感じるのです。まるで私しか気にしていない問題のように感じるのです。なので、このブログポストで、私が英語を使ってきた中で経験してきたことを共有したいと思います。

話せば長くなります

私とsullivanミラノにあった私の自宅で酔っ払いながら、当時取り組んでいた新しい攻撃方法を編み出そうと頑張っていたことを思い出します。あれは1998年のことで、BUGTRAQの参加者なら見ればわかると思いますが、残念な結果に終わりました:http://seclists.org/bugtraq/1998/Dec/79

ここで2行目の "Instead all others" という部分に注目してください。私はいまだに英語が得意ではありませんが、15年以上かけて上達してきましたし、sullivanにいたっては今やアメリカとイギリスの大学で教鞭をとっているぐらいですから彼は相当流暢であることでしょう。(ネタバレ注意:私はまだ流暢ではありません) さて、それはおいといて問題は、私達はTCP/IPの新しい攻撃方法を紹介しようとしていたのに、二人ともそれを英語では全然うまく書けなかったのです。 1998年の当時、私はすでに英語でうまくコミュニケーションが出来ない、英語で書かれた技術文書は労力をつぎ込まないと読めないという事実から、ものすごく制限を受けているように感じていました。 そのことから、私の頭は単純に英語を読むという作業にその50%を使い、実際に読んでいるものを理解するための力は50%以下しか残されていませんでした。

しかしながら、どこかしら、いつも英語はいいものであるということを受け入れていました。人にはいつも技術的な話題では英語を訳さなくて済むようにするアドバイスしています。その理由は、ドキュメントやソースコードのコメントに共通言語を持つことは本当に良いことだと信じていて、実際に英語で書かれた技術文書を理解するために必要なスキルを得るのは多くの人にとって単純な努力だからです。

こうして、1998年から、私は少しずつ英語を勉強して、イタリア語の場合と比較しても変わらないほどにすんなりと英語を読めるようになりました。 それどころか、イタリア語でものを書くのと変わらない速さで英語をかけるようにもなりました。書く能力に関しては極小点にあるとしても、あなたがこのブログを読んでいるという事からも、ちゃんと書けていることは証明されています。基本的に私は砕けた簡単な英語をとても速く書くことで学びました。この方法は普通の場合、プログラミングの領域では自分の考えを表現するのには十分ですが、一般的な話題について書くには不十分です。 たとえば、私は台所で見つけたものについて何か書こうと思った時に必要な単語がほとんどわかりません。あるいは、複文、仮定法などを含んだ文を書くために必要な文法も知りません。 今や私が気になっている話題では容易にコミュニケーションがとれますし、その話題に関しては多かれ少なかれ私が書いたものはみんなが理解できるので、英語を上達させなければ、というプレッシャーは少しずつ減ってきています。。。しかしながら、最近これは私が英語について感じる問題の中では小さなものだとわかったのです。

ヨーロッパ英語、あの面白い言語

なんとかして、自分の用途には快適に英語を読み書きできるようになった一方で、最近まで英語圏の国で実際にコミュニケーションをしたことがほとんどありませんでした。 それまでは、英語をいつも(イギリス以外の)他のヨーロッパの人、例えばフランス、ドイツ、スペインといった国の人々との会話に使ってきました。 いまや、こうした国々で話される英語が英語学校の授業で話される英語となっています。音声学的に言って、この英語はアメリカ英語やイギリス英語とはほとんど無関係です。 これを「BBC英語」と呼ぶ人もいますが、実際は違います。イギリス英語の文法を使っている、音声学的に非常に単純化された英語です。

その 英語によって、実際に世界中の人々が容易にコミュニケーションを図れるようになりました。基本的な文法は習得する上で容易で、数ヶ月訓練すれば話せるようになります。単語の発音はヨーロッパ内のイギリス以外の国々ではほぼ一緒です。素晴らしく便利です。

唯一の問題があって、この英語は実際の英語圏の国、イギリス、アメリカ、カナダといった英語が母国語の国とは無関係だ、ということです。

結局英語は崩れつつある

ここであなたに秘密があります。英語と世界という文脈において誰も語らない秘密です。それは「英語は音声学上、砕けた言語だ」ということです。 イタリアには長い歴史がありますが、政権が統一されたのはつい最近のことです。異なる地域で異なる方言を使っていて、皆それぞれに非常に強い訛りがありました。 1950年より前に、「TV用言語統一」が起きた時に、まだ皆それぞれ自分たちの 方言 を使っていて、イタリア語はほんの少数の人間だけしか習得していない状態でした。 私の家族がよく使っているシチリア語もイタリア語が現れる何世紀も前から存在しています。(http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%81%E3%83%AA%E3%82%A2%E8%AA%9E

それでもなお、面白いのが、ある地域の人が他の地域の人のイタリア語、たとえばスイスの人のイタリア語でさえも理解するのは全く問題がないというところです。 イタリア語は音声学的に地球上で最も単純かつ十分な冗長性を備えた言語の一つです。事実、イタリア語は情報エントロピーが低く、単語は通常子音と母音が程よく混ざっています。 単語を発音するときに特別なルールはなく、すべての文字の発音を知っていて、いくつかある「gl<母音>」「sc<母音>」という特別な組み合わせさえ覚えておけば、99.9%の単語を初見でも正しく発音することができます。

異なる英語を話す国々から来た人々がコミュニケーションをするときに問題があるという事実が、英語が音声学的にいかにおかしいかということを示す大きなヒントとなっています。 たとえば、私や他の非ネイティブの英語話者からすると、イギリス人が口からどんなクソを垂れてるのか、さっぱり全く全然聞き取れません。北米の英語のほうがよっぽど簡単です。

英語のこの「特徴」があるので、私の訛りではなく人が私に話していることを理解する力が問題となります。これは愚見で、前者は私がもっと努力すれば直せる単純なものです。 私見ではありますが、ポール・グレアムが「訛り」について触れたのは、この点においてイギリス人やアメリカ人の良くない姿勢です。言わせてもらいますが、あなた方は私達の話していることを理解していない、私達もあなた方が話していることを理解していない、そして一度露骨に理解しようとする線を制限してしまえば、落ち着いて会話を楽しもうとする人なんてほとんどいなくなってしまいますよ。 私はイギリス人の英語を理解できないとは言いましたが、すぐに復唱するくらいのことはしますよ。

文章だけで英語を学ぶのは本当に厳しい

私の意見では、私が英語学習に時間がかかった理由のひとつは、英語を全く聴き取りをせずに読み取りの練習を始めてしまったことです。 頭の中では、大量の英単語が綴りと実際にはありもしないおかしな発音とが結びついてしまっています。 私からのアドバイスとしては、もしいま英語を勉強しているのであれば、すぐに聴き取りも始めて下さい。

Mac OS Xに付属している "say" コマンドが良い助けになります。 "say" コマンドはたいていの英単語をきちんと発音してくれます。 発音を学ばずに英語を勉強しては いけません

内向的か外向的か

英語に関する経験として最も衝撃を受けたことの一つに、英語を習得していないことがどれほど人を内向的にさせるかという点がありました。 私はイタリアという、殆どの人が外交的な国においても外交的で、シチリアというさらに外交的な土地においても外向的で、外向的という要素で構成された家族内においても外向的でした。 私は思うにいわゆる目立ちたがり屋なのです(本当はそうは思いたくないのですが、非常に外交的です)。 そして、私が英語で話さなければならなくなった途端に、コミュニケーション障壁から外交性はまったく消え去り、その会議に参加したことや、誰かに紹介されることを後悔していました。あれは悪夢でした。

もう手遅れだ、英語を学ぼう

私の意見では、英語は文法が簡単なだけで、共通言語として選択するには間違っています。しかしながら現実は、すでに共通言語としての地位を獲得していて、もうその座を置き換える時間はなく、多くの努力が必要になったとしても英語をうまく話せるようになることを考えるほうがいいでしょう。 これは私がいま行っていることで、さらに改善しようとしている部分でもあります。

私が本当に英語を上達させなければならないと感じた他の理由は、10年後には私は職業としてコードを書くことはおそらくなくなって、選択肢としてIT系の管理職になる、もしくはコードを書くことを期待されていない大きなプロジェクトのリーダーとなる、のどちらかだからです。 開発者として英語が必要だと感じるとすれば、典型的なIT企業の他の部署に移って、さらには多くのプログラマをマネージメントする立場になっていくにしたがってそう思うようになるでしょう。

一方で、ネイティブの英語話者は、多くの人が英語という習得が大変な言語を本当に頑張って勉強しているということをきちんと理解すべきです。英語の勉強は趣味じゃないんです。英語を修得することは多くの人々がコミュニケーションを円滑にするために行なっている多大な尽力なんです。数週間英語を使わなくなっただけで、英語が言うに及ばないほどすぐに下手になってしまうんですから。

いつかは異なる訛りが1つの理解しやすい標準語にまとまって、それが英語話者の共通語となることを願っています。 (翻訳ここまで)

おわりに

ヨーロッパの人でも英語の習得に苦労しているという実体験を赤裸々に公開してもらえると、英語の習得に苦労している自分も励みになります。

僕もアメリカでパスポートから何から盗まれてしまっても自力で帰国するくらいは英語を使えるようになりましたが、それでもネイティブ英語話者の同僚とのコミュニケーションには苦労しています。それは英語だけではない文化の共有ができていなかったりだとか、そういう部分です。 これは英語という言語自体の習得だけではどうしようもない部分でしょう。ただ、ことITの世界の話題に関していえば、誰もが共通の文化をもってコミュニケーションが出来るわけで、その習得に労力を割くことは僕も大いに意味があると実感しています。こうやって彼のエントリをそのまま読めるわけですし。

日本には本当に優秀な技術者がたくさんいるにもかかわらず、英語というただ1点だけで損をしている事例を数多く見ているので、1人でも多くの技術者が1文字でも多くその技術を世界の人々に発信出来る日が早く来ればいいなと願っています。

追記

  • 2013.09.05 00:34 : +Jun Mukaiのコメントをもとに訂正
  • 2013.09.05 10:00 : id:yomoyomoポール・グレアムの原文「創業者の訛り」をリンクとして追加

原著者の許可

実践 ベストプラクティスを適用してみる

はじめに

こんにちは、Go界のジェフ・ベゾスです。シアトルのお父さんがGoでおもしろプログラムを書いているようですが、ちょっと気になったので勝手に添削しました。

元のコード

まず最初のコード。

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "log"
    "os"
)

func main() {
    if len(os.Args) < 1 {
        log.Fatal("You must input a hostname")
    }
    peerCertificates, err := GetCert(os.Args[1])
    if err == nil {
        for i, Cert := range peerCertificates {
            fmt.Printf("i=%d\\n", i)
            fmt.Println(Cert.Issuer.ToRDNSequence())
            fmt.Println(Cert.NotBefore)
            fmt.Println(Cert.NotAfter)
            fmt.Println(Cert.Subject.ToRDNSequence())
        }
    } else {
        log.Fatal(err)
    }
}

func GetCert(host string) ([]*x509.Certificate, error) {
    config := &tls.Config{InsecureSkipVerify: true}
    conn, err := tls.Dial("tcp", host+":443", config)
    var peerCertificates []*x509.Certificate
    if err == nil {
        connectionState := conn.ConnectionState()
        peerCertificates = connectionState.PeerCertificates
    }
    return peerCertificates, err
}

勝手に添削

エラー処理は先に書く

Goには例外処理はありません。通常関数の戻り値を正常値とエラーのタプルとして、異常がある場合にはエラーにError型の何かが入るという形になります。 さて、例外処理がない分、エラーの扱いはCと同様、if等で扱うことになります。ベストプラクティスとしては、 errnil でないパターンを先に処理するべきです。そうしないとif分がネストしやすくなる上にコードが見辛くなります。 この間のOSCON 2013でもエラー処理のベストプラクティスとして話されていました。

エラー処理を先にしてみるとコードもちょっと読みやすくなりました。

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "log"
    "os"
)

func main() {
    if len(os.Args) < 1 {
        log.Fatal("You must input a hostname")
    }
    peerCertificates, err := GetCert(os.Args[1])
    if err != nil {
        log.Fatal(err)
        return
    }

    for i, Cert := range peerCertificates {
        fmt.Printf("i=%d\\n", i)
        fmt.Println(Cert.Issuer.ToRDNSequence())
        fmt.Println(Cert.NotBefore)
        fmt.Println(Cert.NotAfter)
        fmt.Println(Cert.Subject.ToRDNSequence())
    }
}

func GetCert(host string) ([]*x509.Certificate, error) {
    config := &tls.Config{InsecureSkipVerify: true}
    conn, err := tls.Dial("tcp", host+":443", config)
    if err != nil {
        return nil, err
    }
    var peerCertificates []*x509.Certificate
    connectionState := conn.ConnectionState()
    peerCertificates = connectionState.PeerCertificates
    return peerCertificates, err
}

型推論を積極的に使う

GoはCとPythonの中間的な文法や記述をしますが、どちらかというとC寄りではあります。ただ、豊富な標準パッケージや型推論、初期化演算子などで、記述量を減らすことが可能になっています。 変数宣言も出来るだけ初期化と同時に行ったほうが読みやすいコードになります。

func GetCert(host string) ([]*x509.Certificate, error) {
    config := &tls.Config{InsecureSkipVerify: true}
    conn, err := tls.Dial("tcp", host+":443", config)
    if err != nil {
        return nil, err
    }

    connectionState := conn.ConnectionState()
    peerCertificates := connectionState.PeerCertificates // peerCertificatesは初期化もしちゃう
    return peerCertificates, nil
}

さらに言えば必要ない宣言も減らせるので次のように落ち着きます。

func GetCert(host string) ([]*x509.Certificate, error) {
    config := &tls.Config{InsecureSkipVerify: true}
    conn, err := tls.Dial("tcp", host+":443", config)
    if err != nil {
        return nil, err
    }

    connectionState := conn.ConnectionState()
    return connectionState.PeerCertificates, nil
}

添削後

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "log"
    "os"
)

func main() {
    if len(os.Args) < 1 {
        log.Fatal("You must input a hostname")
    }
    peerCertificates, err := GetCert(os.Args[1])
    if err != nil {
        log.Fatal(err)
        return
    }

    for i, Cert := range peerCertificates {
        fmt.Printf("i=%d\\n", i)
        fmt.Println(Cert.Issuer.ToRDNSequence())
        fmt.Println(Cert.NotBefore)
        fmt.Println(Cert.NotAfter)
        fmt.Println(Cert.Subject.ToRDNSequence())
    }
}

func GetCert(host string) ([]*x509.Certificate, error) {
    config := &tls.Config{InsecureSkipVerify: true}
    conn, err := tls.Dial("tcp", host+":443", config)
    if err != nil {
        return nil, err
    }

    connectionState := conn.ConnectionState()
    return connectionState.PeerCertificates, nil
}