<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
>

<channel>
	<title>Google&#039;s Go Guide &#187; 実践Go言語</title>
	<atom:link href="http://golang.jp/tag/%e5%ae%9f%e8%b7%b5go%e8%a8%80%e8%aa%9e/feed" rel="self" type="application/rss+xml" />
	<link>http://golang.jp</link>
	<description>プログラミング言語Goの情報サイト</description>
	<lastBuildDate>Mon, 30 Aug 2010 15:38:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/tag/%e5%ae%9f%e8%b7%b5go%e8%a8%80%e8%aa%9e/feed" />
		<item>
		<title>実践Go言語(part14：翻訳完了)</title>
		<link>http://golang.jp/2010/03/1282</link>
		<comments>http://golang.jp/2010/03/1282#comments</comments>
		<pubDate>Tue, 23 Mar 2010 03:07:51 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1282</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、14回目です。
完全な訳は実践Go言語[日本語訳]にまとめてあります。

ウェブサーバ
Go言語のウェブサーバプログラムを作成して締めくくります。これは実際にはウェブ転送サ [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、14回目です。<br />
完全な訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="web_server">ウェブサーバ</h2>
<p>Go言語のウェブサーバプログラムを作成して締めくくります。これは実際にはウェブ転送サーバの類です。Googleでは<a href="http://chart.apis.google.com/" target="_blank">http://chart.apis.google.com</a>で、データをチャートやグラフに自動変換するサービスを提供していますが、このサービスはデータをクエリパラメータとしてURLに含めなくてはならないため対話的な使い方ができません。ここで紹介するプログラムは、文字を入力するとQRコード（テキストをエンコードした矩形マトリクス）を生成させるために先程のチャートサーバを呼び出す、ちょっとした画面を提供します。生成された画像を携帯電話のカメラで撮影するとURLなどに変換されるので、携帯電話の小さいキーを駆使してURLを入力する手間が省けます。</p>
<p>下はこのプログラム一式です。説明はそのあとに続きます。</p>
<pre>package main

import (
    "flag"
    "http"
    "io"
    "log"
    "strings"
    "template"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
var fmap = template.FormatterMap{
    "html": template.HTMLFormatter,
    "url+html": UrlHtmlFormatter,
}
var templ = template.MustParse(templateStr, fmap)

func main() {
    flag.Parse()
    http.Handle("/", http.HandlerFunc(QR))
    err := http.ListenAndServe(*addr, nil)
    if err != nil {
        log.Exit("ListenAndServe:", err)
    }
}

func QR(c *http.Conn, req *http.Request) {
    templ.Execute(req.FormValue("s"), c)
}

func UrlHtmlFormatter(w io.Writer, v interface{}, fmt string) {
    template.HTMLEscape(w, strings.Bytes(http.URLEscape(v.(string))))
}

const templateStr = `
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;QR Link Generator&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
{.section @}
&lt;img src="http://chart.apis.google.com/chart?chs=300x300&amp;cht=qr&amp;choe=UTF-8&amp;chl={@|url+html}"
/&gt;
&lt;br&gt;
{@|html}
&lt;br&gt;
&lt;br&gt;
{.end}
&lt;form action="/" name=f method="GET"&gt;&lt;input maxLength=1024 size=70
name=s value="" title="Text to QR Encode"&gt;&lt;input type=submit
value="Show QR" name=qr&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
`</pre>
<p><code>main</code>関数までは簡単に説明します。まずサーバのHTTPポート番号のデフォルト値を<code>flag</code>に設定しています。変数<code>templ</code>は目新しい部分で、ページを表示するためにサーバ上で実行されるHTMLテンプレートを構築しています。これについては後でもう少し説明します。</p>
<p><code>main</code>関数で起動パラメータの解析(<code>flag.Parse</code>)後、以前説明した方法でサーバのルートパスと<code>QR</code>関数とを紐付けています。続いてサーバを起動するために<code>http.ListenAndServe</code>が呼び出されます。サーバが動いている間は、ここでブロックされ続けます。</p>
<p><code>QR</code>関数では、入力フォームデータが含まれているリクエストを受け取り、そのフォーム内の<code>s</code>と名付けられたデータを使ってテンプレート処理を実行します。<br />
<code></code></p>
<p>このテンプレートパッケージは、<a href="http://code.google.com/p/json-template" target="_blank">json-template</a>を参考に作られており、とても高機能です。このサーバプログラムでは、ほんの触り程度しか紹介しませんが、テンプレートパッケージの主用途はテンプレートテキストの一部分を<code>templ.Execute</code>に渡されたデータから得られた要素（この場合はフォームの値）で書き換えることです。テンプレートテキスト(<code>templateStr</code>)内の波括弧{}で囲まれている部分でテンプレートの動作を指定します。<code>{.section @}</code>から<code>{.end}</code>までの部分はデータ項目<code>@</code>の値を伴って実行されます。この<code>@</code>は「カレントのアイテム」を表しており、今回の値はフォーム値です。(文字列が空のときは、テンプレートの該当部分は出力されません。)</p>
<p><code>{@|url+html}</code>の箇所では、フォーマッタマップ(<code>fmap</code>)に<code>"url+html"</code>という名前で登録されているフォーマット用関数を使ってデータを処理するよう指定しています。実際に登録されている<code>UrlHtmlFormatter</code>関数では、ウェブページ上で文字列を安全に表示させるためのサニタイズ処理を行います。</p>
<p>テンプレート内のその他の文字列はただのHTMLで、ページが読み込まれたときに表示されます。ここでは駆け足で説明したので、詳しくはテンプレートパッケージの<a href="http://golang.org/pkg/template/" target="_blank">ドキュメント</a>を参照ください。</p>
<p>数行のコードと、データと掛け合わせて出力するHTMLテキストだけで便利なウェブサーバが手に入りました。このようにGo言語はたった数行でも色々なことが行える高機能な言語です。</p>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1282/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1282" />
	</item>
		<item>
		<title>実践Go言語(part13)</title>
		<link>http://golang.jp/2010/03/1276</link>
		<comments>http://golang.jp/2010/03/1276#comments</comments>
		<pubDate>Thu, 18 Mar 2010 06:25:24 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1276</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、13回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

エラー情報
ライブラリルーチンでは、呼び出し元にエラー情報などを返す必要が度々発生します。以前 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、13回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="errors">エラー情報</h2>
<p>ライブラリルーチンでは、呼び出し元にエラー情報などを返す必要が度々発生します。以前説明したように、Go言語の複数戻り値を使うと通常の戻り値と一緒にエラーの詳細情報を返すことが簡単にできます。またエラーは慣例的に<code>os.Error</code>というシンプルなインタフェースを実装しています。</p>
<pre>type Error interface {
    String() string
}</pre>
<p>ライブラリの作成者はこのインタフェースと併せて、より高機能なモデルを自由に実装して構いません。こうすることでエラーを知らせるだけでなく、何らかの状況も提供することができます。この例として、<code>os.Open</code>は下の<code>os.PathError</code>を返しています。</p>
<pre>// PathErrorは、エラーとそれを引き起こした操作及び
// ファイルパスが記録されます。
type PathError struct {
    Op string    // "open", "unlink", など
    Path string  // 関連ファイル
    Error Error  // システムコールからの戻り値
}

func (e *PathError) String() string {
    return e.Op + " " + e.Path + ": " + e.Error.String()
}</pre>
<p><code>PathError</code>の<code>String</code>メソッドは次のような文字列を生成します。<code></code></p>
<pre>open /etc/passwx: no such file or directory</pre>
<p>このようにエラー情報内に問題の起きたファイル名、操作、引き金となったオペレーティングシステムのエラーを含んでいると、エラーとなった呼び出し箇所から離れた箇所でエラー情報を出力したときにも役立ちます。「そのようなファイルやディレクトリはありません」と単に返されるより、多くの情報を与えてくれます。</p>
<p>呼び出し元で、エラーの正確な詳細情報が必要なときは、型スイッチまたは型アサーションを使い特定のエラーを探して詳細情報を得ることができます。たとえば<code>PathErrors</code>の場合、内部の<code>Error</code>フィールドを調べることでリカバリ可能か判断できることがあります。</p>
<pre>for try := 0; try &lt; 2; try++ {
    file, err = os.Open(filename, os.O_RDONLY, 0)
    if err == nil {
        return
    }
    if e, ok := err.(*os.PathError); ok &amp;&amp; e.Error == os.ENOSPC {
        deleteTempFiles()  // 空き容量を回復
        continue
    }
    return
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1276/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1276" />
	</item>
		<item>
		<title>実践Go言語(part12)</title>
		<link>http://golang.jp/2010/03/1260</link>
		<comments>http://golang.jp/2010/03/1260#comments</comments>
		<pubDate>Wed, 17 Mar 2010 06:16:38 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1260</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、12回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

並列性
通信による共有
並列プログラミングは大きなトピックではありますが、ここではGo言語の仕 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、12回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="concurrency">並列性</h2>
<h3 id="sharing">通信による共有</h3>
<p>並列プログラミングは大きなトピックではありますが、ここではGo言語の仕様の中で特徴的な部分だけを取り上げます。</p>
<p>一般的な環境における並列プログラミングは、共有変数にアクセスするためには適切な実装が厳密に求められるため扱いにくいものでした。Go言語では、共有変数をチャネル上で引き回し、実行中の異なるスレッドからは実際に同時アクセスさせないという今までとは異なる手法を推奨しています。あるタイミングで値にアクセスできるゴルーチンはひとつだけなので、設計上データ競合は起きえません。</p>
<blockquote><p>共有メモリを使った通信は行わず、代わりに通信を使うことでメモリを共有するようにしてください。</p></blockquote>
<p>この手法は、過剰となる側面もあります。参照カウンタであれば、たとえば整数型の変数とミューテックスを併用するほうが最適かもしれません。しかし、高水準な手法として、アクセス制御のためにチャネルを使うことは、明解で正確なプログラムを記述することをより容易くします。</p>
<p>このモデルについて考える手立てとして、1台のCPU上で動いている典型的なシングルスレッドプログラムがあると仮定します。これには同期プリミティブは不要です。同様に同期が不要であるインスタンスを新しく起動して、これらスレッド間を通信させます。この通信が同期していれば、それ以外の同期はとりあえず必要ありません。このモデルと一致する例としては、Unixのパイプラインが良く知られています。Go言語におけるこの並列性へのアプローチは、Hoare氏のCommunicating Sequential Processes (CSP)が基になっており、Unixパイプにおけるタイプセーフの汎用化にもこれが見受けられます。</p>
<h3 id="goroutines">ゴルーチン</h3>
<p>ゴルーチンと呼ぶようにした理由は、スレッド、コルーチン、プロセスといった既存の用語では正確に伝わらないためです。ゴルーチンが持つモデルは単純で、その役割は同一アドレス空間内で他のゴルーチン同士を並列実行することです。またゴルーチンは軽量で、スタック空間を割り当てるより若干コストがかかる程度です。開始時のスタックサイズは節約のため小さく取り、必要に応じてヒープ領域を割り当て(自由に)拡張します。</p>
<p>ゴルーチンはOSの複数スレッド上へ多重化されるので、ひとつが例えばI/O待ちなどでブロックされていても、他のゴルーチンの実行は継続します。ゴルーチンの仕組みによってスレッドを作成・管理する複雑さの大部分が軽減されます。</p>
<p>関数またはメソッドの呼び出しを新規ゴルーチンとして実行するには、呼び出しの直前にキーワードgoと記述してください。呼び出しが完了した時点で、すでにゴルーチンは作成されています。(この効能はUnixシェルにてバックグラウンドでコマンドを実行するために使用する「<code>&amp;</code>」表記とほぼ同じです。)</p>
<pre>go list.Sort()  // list.Sortを並列実行する(処理の完了は待たない)</pre>
<p>関数リテラルを使うと手軽にゴルーチンが実行できます。</p>
<pre>func Announce(message string, delay int64) {
    go func() {
        time.Sleep(delay)
        fmt.Println(message)
    }()  // 括弧に注意。関数を呼び出すために必要。
}</pre>
<p>Go言語における関数リテラルはクロージャです。このとき関数内から参照されている変数は関数が実行している間、生存しつづけます。</p>
<p>この例では関数が完了したことを通知する手立てがないため、あまり実践的ではありません。完了通知を行うにはチャネルを使います。</p>
<h3 id="channels">チャネル</h3>
<p>マップと同じくチャネルは参照型であり、<code>make</code>を使って割り当てられます。作成時にオプションの整数パラメータを指定すると、チャネルのバッファサイズとして使われます。この値のデフォルトはゼロであり、ゼロのときバッファリングは行われず同期チャネルとなります。</p>
<pre>ci := make(chan int)            // 整数型のバッファなしチャネル
cj := make(chan int, 0)         // 整数型のバッファなしチャネル
cs := make(chan *os.File, 100)  // Fileへのポインタ型のバッファありチャネル</pre>
<p>チャネルは、値の交換および同期という通信機能を兼ね備えており、2つの計算処理(ゴルーチン)が予期しない状態とならないことを保証します。</p>
<p>チャネルを利用した優れたイディオムはたくさんありますが、手始めにひとつ紹介します。前のセクションではソート処理をバックグラウンドで起動しましたが、これにチャネルを使って起動したゴルーチンのソート完了を待つよう変更できます。</p>
<pre>c := make(chan int)  // チャネルの割り当て
// ゴルーチンとしてsortを起動。完了時にチャネルへ通知
go func() {
    list.Sort()
    c &lt;- 1  // 通知を送信。値は何でも良い
}()
doSomethingForAWhile()
&lt;-c   // sortの完了待ち。送られてきた値は破棄</pre>
<p>受信側では常に、受信可能なデータが来るまでブロックされます。送信側はチャネルがバッファリングしていないときは、受信側が値を受信するまでブロックされます。チャネルがバッファリングしているときは、送信側がブロックされるのは値がバッファへコピーされる間だけです。このためバッファがいっぱいのときは、受信側で値を取り出すまで待機します。</p>
<p>スループットを制限するようなケースで、バッファありチャネルをセマフォのように使うことができます。下の例では、入って来たリクエストは<code>handle</code>に渡されます。その中でまず値をチャネルへ送信し、リクエストを処理したのちチャネルから値を受信しています。チャネルのバッファが持つ容量を利用して<code>process</code>の同時呼び出し数を制限しています。</p>
<pre>var sem = make(chan int, MaxOutstanding)

func handle(r *Request) {
    sem &lt;- 1    // アクティブキューの空き待ち
    process(r)  // 時間のかかる処理
    &lt;-sem       // 完了。次のリクエストを処理可能にする
}

func Serve(queue chan *Request) {
    for {
        req := &lt;-queue
        go handle(req)  // handleの終了待ちはしない
    }
}</pre>
<p>次も同様のアイデアで、一定数の<code>handle</code>ゴルーチンを起動しておき、その中でリクエストチャネルから全て読み込んでいます。ここではゴルーチンの数で<code>process</code>の同時呼び出し数を制限しています。この<code>Serve</code>関数自体も、終了指示を受信するためのチャネルを引数として受け取り、ゴルーチンを起動したあと、このチャネルを受信することでブロックしています。</p>
<pre>func handle(queue chan *Request) {
    for r := range queue {
        process(r)
    }
}

func Serve(clientRequests chan *clientRequests, quit chan bool) {
    // Start handlers
    for i := 0; i &lt; MaxOutstanding; i++ {
        go handle(clientRequests)
    }
    &lt;-quit  // 終了指示待ち
}</pre>
<h3 id="chan_of_chan">チャネル内のチャネル</h3>
<p>Go言語の特徴のなかで重要なもののひとつは、チャネルがメモリを割り当てることができ、かつ他の値と同じように引き回すことができる「優れた値」であることです。この機能は一般的に並列、非多重化を安全に実装するために使われます。</p>
<p>前セクションの例における<code>handle</code>はリクエストを処理するための理想的なハンドラではありましたが、そこで扱っていた<code>Request</code>型は未定義でした。もしその型に応答用チャネルが含まれていれば、各クライアント側でそれぞれ処理結果を受信する経路を用意することができます。下は<code>Request</code>型の定義の概略です。</p>
<pre>type Request struct {
    args        []int
    f           func([]int) int
    resultChan  chan int
}</pre>
<p>リクエストオブジェクト内の処理結果受信用チャネルと同様に、クライアント側で関数とその引数も準備します。</p>
<pre>func sum(a []int) (s int) {
    for _, v := range a {
        s += v
    }
    return
}

request := &amp;Request{[]int{3, 4, 5}, sum, make(chan int)}
// リクエスト送信
clientRequests &lt;- request
// 応答待ち
fmt.Printf("answer: %d\n", &lt;-request.resultChan)</pre>
<p>サーバ側で変更するのは、ハンドラ関数だけです。</p>
<pre>func handle(queue chan *Request) {
    for req := range queue {
        req.resultChan &lt;- req.f(req.args)
    }
}</pre>
<p>これを現実的なコードにするには、やるべきことが多々残されていることは明らかですが、このコードはあくまで帯域制限、平行処理、非ブロック型RPC機構を実装したフレームワークであり、相互排他は考慮していません。</p>
<h3 id="parallel">並列化</h3>
<p>これらの考え方のもう一つの応用は、複数のCPUコアすべてを使い計算を並列処理することです。計算処理を個々に分割できるのであれば、各計算の完了を伝えるチャネルを用意することで並列化可能です。</p>
<p>下のサンプルのように、アイテムを格納した<code>Vector</code>上で実行される高コストの演算処理があり、またその各アイテムにて演算される値同士が、お互い関連性を持たないと仮定します。</p>
<pre>type Vector []float64

// v[i], v[i+1] ... v[n-1]までを演算処理に適用
func (v Vector) DoSome(i, n int, u Vector, c chan int) {
    for ; i &lt; n; i++ {
        v[i] += u.Op(v[i])
    }
    c &lt;- 1    // この部分が終わったことを伝達
}</pre>
<p>データをCPUコア数分割し、ループでコア毎に処理をひとつ起動します。演算処理が完了する順番は不定ですが、それは問題ではありません。単に全ゴルーチンを起動後、チャネルから受信した完了通知数をカウントするだけです。</p>
<pre>const NCPU = 4  // CPUコア数

func (v Vector) DoAll(u Vector) {
    c := make(chan int, NCPU)  // 任意だが、バッファリングしたほうが賢明
    for i := 0; i &lt; NCPU; i++ {
        go v.DoSome(i*len(v)/NCPU, (i+1)*len(v)/NCPU, u, c)
    }
    // チャネルを空に
    for i := 0; i &lt; NCPU; i++ {
        &lt;-c    // 処理の完了をひとつ待つ
    }
    // すべて完了
}</pre>
<p><code>gc</code>（<code>6g</code>等）の現実装のデフォルトでは、このコードは各CPUコアへ並列化はされません。ユーザ処理に対してはコアをひとつしか使用しないようになっているためです。システムコールで任意の数のゴルーチンをブロックすることは可能ですが、デフォルトで実行されるユーザレベルコードは常にひとつだけです。これはもっと賢くあるべきで、また今後賢くしていく予定はありますが、そうなるまでCPUを並列処理させたいときはコードを同時実行したいゴルーチン数をランタイムに指定してください。この指定方法は2つあり、環境変数<code>GOMAXPROCS</code>に使用するコア数(デフォルト1)を設定してからジョブを実行するか、もしくは<code>runtime</code>パッケージをインポートし、<code>runtime.GOMAXPROCS(NCPU)</code>を呼び出してください。また、スケジューリングとランタイムが改善されたときは、この設定は不要となる予定です。</p>
<h3 id="leaky_buffer">溢れるバッファ</h3>
<p>並列プログラミング向け機能を利用して、より実装が簡単な非並列処理を記述することもできます。下はRPCパッケージから取り出した例です。クライアント側のゴルーチンではループ内でどこかのソース(おそらくネットワーク)からデータを受信します。バッファの割り当て・開放を減らすために使わなくなったバッファはリストに格納しておきます。これを実現するためにバッファありチャネルを使い、このチャネルが空のときは新たにバッファを割り当てます。受信したメッセージをバッファに格納すると、そのバッファは<code>serverChan</code>経由でサーバへ送信されます。</p>
<pre>var freeList = make(chan *Buffer, 100)
var serverChan = make(chan *Buffer)

func client() {
    for {
        b, ok := &lt;-freeList  // バッファがあれば取得
        if !ok {              // なければ新たに割り当てる
            b = new(Buffer)
        }
        load(b)              // 次のメッセージをネットから読み込む
        serverChan &lt;- b      // サーバへ送信
    }
}</pre>
<p>サーバ側のループではクライアントからメッセージを受信し処理を行ったあと、バッファリストにバッファを返却します。</p>
<pre>func server() {
    for {
        b := &lt;-serverChan    // 作業待ち
        process(b)
        _ = freeList &lt;- b    // 空きがあればバッファを再利用
    }
}</pre>
<p>クライアントの非ブロック受信では、利用可能であればバッファリストからバッファを取得します。利用可能なバッファがないときは新しくバッファを割り当てます。サーバの<code>freeList</code>への非ブロック送信は、バッファリストがいっぱいでなければ<code>b</code>を<code>freeList</code>に戻します。バッファが溢れたときはガーベジコレクタによって回収されます。(送信演算子をブランク識別子へ代入することで非ブロック送信となりますが、操作が成功したかどうかは無視されます。) この実装では、ある境界線で溢れてしまうバケツのような空きバッファリストを作成し、冗長なコードを記述する代わりにチャネルのバッファとガーベジコレクタ任せにしています。</p>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1260/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1260" />
	</item>
		<item>
		<title>実践Go言語(part11)</title>
		<link>http://golang.jp/2010/03/1252</link>
		<comments>http://golang.jp/2010/03/1252#comments</comments>
		<pubDate>Fri, 12 Mar 2010 07:46:49 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1252</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、11回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

埋込み
Go言語には型によるサブクラス化という典型的な概念はありませんが、構造体またはインタフ [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、11回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="embedding">埋込み</h2>
<p>Go言語には型によるサブクラス化という典型的な概念はありませんが、構造体またはインタフェースに型を埋込み、実装を「借りる」仕組みがあります。</p>
<p>インタフェースの埋込みはとても単純です。下は以前説明した<code>io.Reader</code>と<code>io.Writer</code>インタフェースの定義です。</p>
<pre>type Reader interface {
    Read(p []byte) (n int, err os.Error)
}

type Writer interface {
    Write(p []byte) (n int, err os.Error)
}</pre>
<p><code>io</code>パッケージではこれと同じように、オブジェクトに対しメソッドの実装を規定するためのインタフェースが、他にもいくつかエクスポートされています。たとえば、<code>Read</code>と<code>Write</code>両方を持つインタフェース<code>io.ReadWriter</code>があります。これら2つのメソッドを明示的に記述することで<code>io.ReadWriter</code>を定義することもできますが、次のようにして2つのインタフェースを埋込んで新しいインタフェースを作成するほうがより簡単で、意図が伝わりやすくなります。</p>
<pre>// ReadWriteは、基本的なメソッドReadとWriteをグルーピングしたインタフェース
type ReadWriter interface {
    Reader
    Writer
}</pre>
<p>このようにすることで、<code>Reader</code>が行えること、および<code>Writer</code>が行えることを<code>ReadWriter</code>が兼ね備えていて、このインタフェースが埋込みインタフェース（メソッド群内に共通のメソッドを持っていてはならない）の結合により作られていることが見て取れます。ただしインタフェース内に埋込むことができるのはインタフェースだけです。</p>
<p>この基本的な考え方は構造体にもあてはまりますが、構造体の場合はより広範囲に渡る影響があります。<code>bufio</code>パッケージは2つの構造体型、<code>bufio.Reader</code>と<code>bufio.Writer</code>を持ち、当然それぞれパッケージ<code>io</code>の対応するインタフェースを実装しています。<code>bufio</code>ではさらに埋込みを利用して、ひとつの構造体に<code>Reader</code>と<code>Writer</code>を組み込んでバッファ付きの読み書きを実装しています。下の例で構造体内に型を列挙していますが、このときフィールド名は付けていません。</p>
<pre>// ReadWriterは、ReaderとWriterのポインタを格納している
// これはio.ReadWriterの実装
type ReadWriter struct {
    *Reader
    *Writer
}</pre>
<p>この構造体はこう書き換えることも可能です。</p>
<pre>type ReadWriter struct {
    reader *Reader
    writer *Writer
}</pre>
<p>ただこうした場合は、下のようにして呼び出しを転送するメソッドを用意し、フィールド内の各メソッドを実装し<code>io</code>インタフェースを満たすようにしなければなりません。</p>
<pre>func (rw *ReadWriter) Read(p []byte) (n int, err os.Error) {
    return rw.reader.Read(p)
}</pre>
<p>しかし、直接構造体を埋込んでしまえば、この冗長な記述は要らなくなります。埋込まれた型が持っているメソッドは自動で持ち上げられるため、すなわち<code>bufio.ReadWriter</code>は<code>bufio.Reader</code>と <code>bufio.Writer</code>のメソッドを持つだけでなく、3つのインタフェース(<code>io.Reader</code>、<code>io.Writer</code>、<code>io.ReadWriter</code>)の全てを満たすようになります。</p>
<p>埋込みとサブクラス化では大きな違いがあります。型を埋込んでいるとき、埋込んだ型が持っているメソッドは埋込み先のメソッドともなりますが、実行しているメソッドのレシーバは埋込み先の型ではなく、あくまで元の型です。サンプルコードの <code>bufio.ReadWriter</code>の<code>Read</code>メソッドが実行されることと、先程の転送メソッドが実行されることは結果としてまったく同じです。(レシーバは<code>ReadWriter</code>フィールドの<code>reader</code>で、<code>ReadWriter</code>自身ではありません。)</p>
<p>また、埋込みを使うことで少し扱いやすくもなります。下の例では、通常の名前付きフィールドと並んで、埋込みフィールドを記述しています。</p>
<pre>type Job struct {
    Command string
    *log.Logger
}</pre>
<p>これで<code>Job</code>型は、<code>log.Logger</code>型が持つ<code>Log</code>、<code>Logf</code>といったメソッドを持つようになりました。もちろん、<code>Logger</code>にフィールド名を与えることはできますが、それは必須ではありません。これで、<code>Job</code>を使ってログが記録できるようになりました。</p>
<pre>job.Log("starting now...")</pre>
<p>この<code>Logger</code>は普通の構造体フィールドであるため、いままで通りの方法で初期化が行えます。</p>
<pre>func NewJob(command string, logger *log.Logger) *Job {
    return &amp;Job{command, logger}
}</pre>
<p>埋込まれているフィールドを直接参照しなければならないときは、フィールドの型名(パッケージ名は不要)をフィールド名として用います。つまり<code>Job</code>型である変数<code>job</code>の<code>*log.Logger</code>にアクセスしたいときは<code>job.Logger</code>と書きます。これは<code>Logger</code>のメソッドに手を加えたいときに役立ちます。</p>
<pre>func (job *Job) Logf(format string, args ...) {
    job.Logger.Logf("%q: %s", job.Command, fmt.Sprintf(format, args))
}</pre>
<p>型を埋込むことで名前の競合が発生する恐れがありますが、その解決ルールは単純です。最初に、フィールドまたはメソッド<code>X</code>は、その他の、より深い入れ子内にある<code>X</code>を隠蔽します。たとえば<code>log.Logger</code>に<code>Command</code>と名づけられたフィールドまたはメソッドが含まれていても、<code>Job</code>の<code>Command</code>フィールドがそれより優先されます。</p>
<p>2番目として、同一の入れ子階層に同じ名前が現れたとき、通常ではエラーとなります。たとえば<code>Job</code>構造体に、<code>Logger</code>と名づけられた別のフィールドまたはメソッドが含まれているとき<code>log.Logger</code>の埋め込みは不正です。ただし、このとき重複した名前が、型定義より外側のプログラムから一切アクセスされなければ大丈夫です。この決まりによって、埋め込まれた型へ外部から変更を加えてもある程度保護されます。つまり、フィールドの追加で他の型が持つフィールドとかち合ってしまっても、どちらのフィールドも一切使用されることがなければ何ら問題ありません。</p>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1252/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1252" />
	</item>
		<item>
		<title>実践Go言語(part10)</title>
		<link>http://golang.jp/2010/03/1245</link>
		<comments>http://golang.jp/2010/03/1245#comments</comments>
		<pubDate>Wed, 10 Mar 2010 04:44:45 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1245</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、10回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

インタフェースとそれ以外の型
インタフェース
Go言語のインタフェースは、オブジェクトの振舞い [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、10回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="interfaces_and_types">インタフェースとそれ以外の型</h2>
<h3 id="interfaces">インタフェース</h3>
<p>Go言語のインタフェースは、オブジェクトの振舞いを規定する手立てです。このセクションではインタフェースにより実現できることすべてを説明します。今まですでに2、3の簡単な例を見てきました。たとえばカスタム出力は<code>String</code>メソッドを実装することで作られ、一方<code>Fprintf</code>は<code>Write</code>メソッドによって出力先をどこへでも変更できます。Go言語のコードでは、通常インタフェースは1～2個のメソッドしか持たず、また<code>Write</code>メソッドを持つ<code>io.Writer</code>のようにたいていメソッド名と関連した名前が付けられます。</p>
<p>型には複数のインタフェースを実装することができます。たとえばあるコレクション型が<code>Len()</code>、<code>Less(i, j int) bool</code>、<code>Swap(i, j int)</code>メソッドを持つ<code>sort.Interface</code>を実装していれば<code>sort</code>パッケージのルーチンを使ってソートが可能になり、その上さらに独自の出力メソッドを実装することもできます。下の例の<code>Sequence</code>型は、少々不自然ですがこれらをすべて実装しています。</p>
<pre>type Sequence []int

// sort.Interfaceに必要な全メソッドを実装
func (s Sequence) Len() int {
    return len(s)
}
func (s Sequence) Less(i, j int) bool {
    return s[i] &lt; s[j]
}
func (s Sequence) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

// 出力用メソッド - 出力前に要素を並び替え
func (s Sequence) String() string {
    sort.Sort(s)
    str := "["
    for i, elem := range s {
        if i &gt; 0 {
            str += " "
        }
        str += fmt.Sprint(elem)
    }
    return str + "]"
}</pre>
<h3 id="conversions">変換</h3>
<p>さきほどの<code>Sequence</code>の<code>String</code>メソッドを変更して、<code>Sprint</code>が本来持っているスライス出力機能を利用するようにしました。<code>Sprint</code>を呼び出す前に<code>Sequence</code>を純粋な<code>[]int</code>に変換することで、既存の処理を利用することが可能になります。</p>
<pre>func (s Sequence) String() string {
    sort.Sort(s)
    return fmt.Sprint([]int(s))
}</pre>
<p>このとき変換が行われ、<code>s</code>がただのスライスとみなされるため、スライスに規定されている書式で文字列が返されます。ここで変換を行われなければ、<code>Sprint</code>は<code>Sequence</code>の<code>String</code>メソッドを見つけ出し、呼び出しを無限に繰り返してしまいます。この2つの型(<code>Sequence</code>と<code>[]int</code>)は名前を除けば同一であるため、これらの型の間における変換は問題なく行われます。この変換では新しい値が作られることはなく、既存の値が一時的に新しい型を持つかのような働きをします。(これと異なる変換もあります。たとえば整数を浮動小数点へ変換したときは新しく値が作成されます。)</p>
<p>Go言語のプログラムでは、異なるメソッド群を使用するために式の型を変換することがよく行われます。例として、既存の型<code>sort.IntArray</code>を使ってサンプルプログラム全体を下のように軽量化することが可能です。</p>
<pre>type Sequence []int

// 出力用メソッド - 出力する前に要素を並び替え
func (s Sequence) String() string {
    sort.IntArray(s).Sort()
    return fmt.Sprint([]int(s))
}</pre>
<p>これで、<code>Sequence</code>に複数のインタフェース(ソートと出力)を実装する代わりに、データを複数の型(<code>Sequence</code>、 <code>sort.IntArray</code>、<code>[]int</code>)に変換できることを利用して各機能を実現できるようになりました。このような使い方をすることは実際にはほとんどありませんが効果的な使い方です。</p>
<h3 id="generality">概説</h3>
<p>ある型がインタフェースをひとつだけ実装していて、そのインタフェースのメソッド以外にエクスポートされたメソッドを持たないならば、型自体のエクスポートは不要です。インタフェースだけをエクスポートすることで、次の点を明白にすることができます。ひとつは、重要なのは実装ではなく振舞いであること。もうひとつは、振舞いは同じでも異なる機能を持った別個の実装であることです。また、共通メソッドを実装している各箇所で、その都度ドキュメントを記述する手間が省けるという利点もあります。</p>
<p>このような場合は、コンストラクタは実装している型ではなく、インタフェース値を返さなければなりません。一例として、ハッシュライブラリの<code>crc32.NewIEEE()</code>と<code>adler32.New()</code>では、双方とも<code>hash.Hash32</code>インタフェース型の値を返します。Go言語プログラムでこのハッシュアルゴリズムをAdler-32からCRC-32に変更するために必要なのは、コンストラクタの呼び出しを入れ替えるだけです。それ以外のコードは、ハッシュアルゴリズムの変更による影響を受けません。</p>
<p>同様のアプローチにより、<code>crypto/block</code>パッケージのストリーム暗号アルゴリズムは、一連のブロック暗号から独立しています。これらは特定の実装を返すのではなく、<code>bufio</code>パッケージにならって<code>Cipher</code>インタフェースをラップした<code>hash.Hash</code>、<code>io.Reader</code>、<code>io.Writer</code>いずれかのインタフェース値を返します。</p>
<p>下は<code>crypto/block</code>内のインタフェースです。</p>
<pre>type Cipher interface {
    BlockSize() int
    Encrypt(src, dst []byte)
    Decrypt(src, dst []byte)
}

// NewECBDecrypterは、rからデータを読み込み、
// c内の電子コードブック(ECB)モードを使って復号化を行うReaderを返します。
func NewECBDecrypter(c Cipher, r io.Reader) io.Reader

// NewCBCDecrypterは、rからデータを読み込み、
// c内の暗号ブロックチェイニング(CBC)モードと初期化ベクタivを使って
// 復号化を行うReaderを返します。
func NewCBCDecrypter(c Cipher, iv []byte, r io.Reader) io.Reader</pre>
<p><code>NewECBDecrypter</code>および<code>NewCBCReader</code>で扱うことができるのは、特定の暗号化アルゴリズムやデータソースではなく、どの<code>Cipher</code>インタフェースの実装であっても、またどの<code>io.Reader</code>でも適用することが可能です。これらは<code>io.Reader</code>インタフェース値を返すため、ECB暗号化をCBC暗号化と入れ替えるときは部分的な変更だけですみます。コンストラクタを呼び出している箇所は変更が必要ですが、その周囲のコードではコンストラクタから返されるのは<code>io.Reader</code>だけとみなしていれば違いに気づくことさえないでしょう。</p>
<h3 id="interface_methods">インタフェースとメソッド</h3>
<p>ほぼすべての型に対してメソッドを付け加えることができるので、これはすなわち、どのインタフェースであっても、ほとんどの型に実装可能であると言えます。この実例のひとつが、<code>Handler</code>インタフェースを定めている<code>http</code>パッケージにあります。<code>Handler</code>を実装しているすべてのオブジェクトで、HTTPリクエストを処理することが可能です。</p>
<pre>type Handler interface {
    ServeHTTP(*Conn, *Request)
}</pre>
<p>ここでは簡略化のため、POSTは無視してHTTPリクエストが常にGETであると仮定します。 (この簡略化がハンドラの書き方に影響を及ぼすことはありません。) 下は、ページの訪問回数を単に数えるだけのハンドラの実装一式です。</p>
<pre>// 単純なカウントサーバ
type Counter struct {
    n int
}

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
    ctr.n++
    fmt.Fprintf(c, "counter = %d\n", ctr.n)
}</pre>
<p>(今回のテーマを気にとめつつ、<code>Fprintf</code>がどのようにしてHTTP接続を出力するか注意してみてください。)<br />
参考までに、こういったサーバをURLパスに割り当てる手順です。</p>
<pre>import "http"
...
ctr := new(Counter)
http.Handle("/counter", ctr)</pre>
<p>ところで、なぜ<code>Counter</code>を構造体としているのでしょうか。必要なのは整数ひとつだけのはずです。(ただし値が増えたことを呼び出し側にも伝わるように、レシーバはポインタである必要があります。)</p>
<pre>// 単純なカウントサーバ
type Counter int

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
    *ctr++
    fmt.Fprintf(c, "counter = %d\n", *ctr)
}</pre>
<p>自作プログラムが内部ステータスを持っていて、そこにページが訪問されたことを通知しなければならないとしたらどうすればよいでしょうか。このようなときは、次のようにチャネルとウェブページとを関連付けてください。</p>
<pre>// 訪問がある度に通知を送信するチャネル
// (たぶんバッファリングされている必要がある)
type Chan chan *http.Request

func (ch Chan) ServeHTTP(c *http.Conn, req *http.Request) {
    ch &lt;- req
    fmt.Fprint(c, "notification sent")
}</pre>
<p>最後に、パス<code>/args</code>を訪問したときにサーバプログラムを起動した際に与えられた引数を出力するようにしてみましょう。引数の出力関数は下のように簡単に書けます。</p>
<pre>func ArgServer() {
    for i, s := range os.Args {
        fmt.Println(s)
    }
}</pre>
<p>これをHTTPサーバへ変更していきます。さきほどの<code>ArgServer</code>関数を適当な型(値は何でも良い)のメソッドとすることもできますが、それより良い方法があります。メソッドはポインタとインタフェース以外すべての型に定義することができるため、関数に対してメソッドを書くことも可能です。<code>http</code>パッケージには、下のコードが含まれています。</p>
<pre>// HandlerFunc型は、通常の関数をHTTPハンドラとして
// 使用可能にするためのアダプタです。
// fが適切なシグネチャを持つ関数であれば、HandlerFunc(f)は
// fを呼び出すハンドラオブジェクトとなります。
type HandlerFunc func(*Conn, *Request)

// ServeHTTPはf(c, req)を呼び出す
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
    f(c, req)
}</pre>
<p><code>HandlerFunc</code>は<code>ServeHTTP</code>メソッドを持つ型であるため、この型の値はHTTPリクエストを処理できます。メソッドの実装を見てください。このメソッドのレシーバは関数<code>f</code>であり、メソッド内で<code>f</code>を呼び出しています。これは少々風変わりではありますが、前出のチャネルをレシーバとしてそのチャネルへ送信するメソッドと大差ありません。</p>
<p><code>ArgServer</code>をHTTPサーバにするため、まずは正しいシグネチャを持つように修正します。</p>
<pre>// 引数サーバ
func ArgServer(c *http.Conn, req *http.Request) {
    for i, s := range os.Args {
        fmt.Fprintln(c, s)
    }
}</pre>
<p>これで<code>ArgServer</code>は<code>HandlerFunc</code>と同じシグネチャを持つようになったので、以前<code>Sequence</code>を<code>IntArray.Sort</code>を使用するため<code>IntArray</code>に変換したときと同様に、<code>ArgServer</code>を<code>HandlerFunc</code>内のメソッドを使用するために<code>HandlerFunc</code>型に変換可能になりました。このセットアップを行うコードは次のように簡潔に書けます。</p>
<pre>http.Handle("/args", http.HandlerFunc(ArgServer))</pre>
<p>誰かが<code>/args</code>ページを訪問したときに呼び出されるハンドラは、値は<code>ArgServer</code>で型は<code>HandlerFunc</code>となりました。まず、HTTPサーバによって<code>ArgServer</code>をレシーバとして<code>HandlerFunc</code>型の<code>ServeHTTP</code>メソッドが実行され、続いて<code>HandlerFunc.ServeHTTP</code>内の<code>f(c, req)</code>を通して<code>ArgServer</code>が呼び出されます。そのあと引数の表示が行われます。</p>
<p>このセクションで、構造体、整数、チャネル、関数を使ってHTTPサーバを作成したのは、インタフェースがまさにメソッド群であり、(ほとんど)すべての型に対して定義できることを示すためです。</p>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1245/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1245" />
	</item>
		<item>
		<title>実践Go言語(part9)</title>
		<link>http://golang.jp/2010/03/1239</link>
		<comments>http://golang.jp/2010/03/1239#comments</comments>
		<pubDate>Fri, 05 Mar 2010 06:38:05 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1239</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、9回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

メソッド
ポインタ vs. 値
メソッドは、名前がつけられていればポインタとインタフェースを除く [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、9回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="methods">メソッド</h2>
<h3 id="pointers_vs_values">ポインタ vs. 値</h3>
<p>メソッドは、名前がつけられていればポインタとインタフェースを除くすべての型に定義することができます。（レシーバは構造体である必要はありません。）</p>
<p>以前、スライスの説明のところで書いた<code>Append</code>関数を今度はスライスのメソッドとして定義してみます。これにはまず、メソッドと結びつけるために新たに名前付きの型を宣言し、メソッドにこの型のレシーバを定義します。</p>
<pre>type ByteSlice []byte

func (slice ByteSlice) Append(data []byte) []byte {
    // 本体部分は前と全く同じ
}</pre>
<p>このままでは、更新したスライスをメソッドから返す必要がまだ残っています。レシーバとして<code>ByteSlice</code>へのポインタを受け取るようメソッドを定義しなおすことによって、その問題を回避できます。こうすれば呼び出し元のスライスに対しメソッド内から上書き可能になります。</p>
<pre>func (p *ByteSlice) Append(data []byte) {
    slice := *p
    // 本体部分は上とおなじだが、returnは除外
    *p = slice
}</pre>
<p>実のところ、もう少し改善可能です。たとえば、この関数を標準的な<code>Write</code>メソッドに合わせるように変更すると下のようになります。</p>
<pre>func (p *ByteSlice) Write(data []byte) (n int, err os.Error) {
    slice := *p
    // これも上と同じ
    *p = slice
    return len(data), nil
}</pre>
<p>このようにすることで<code>*ByteSlice</code>型は、利便性の高い標準インタフェース<code>io.Writer</code>を満たすようになり、下の例のようにスライスに対し出力することが可能となります。</p>
<pre>    var b ByteSlice
    fmt.Fprintf(&amp;b, "This hour has %d days\n", 7)</pre>
<p>上で<code>ByteSlice</code>のアドレスを渡しているのは、<code>*ByteSlice</code>でなければ<code>io.Writer</code>インタフェースを満たさないためです。レシーバとしてポインタまたは値のどちらを受け取るかによって、次の違いがあります。レシーバとして値を受け取るメソッドでは、ポインタまたは値で呼び出すことができますが、ポインタを受け取るメソッドでは、ポインタでしか呼び出すことができません。これは後者ではメソッド内でレシーバを変更可能であるためです。(複製された値に加えた変更は破棄されてしまうため。）</p>
<p>ちなみに、<code>Write</code>をバイトのスライスで使うというアイデアは<code>bytes.Buffer</code>で実装済です。</p>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1239/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1239" />
	</item>
		<item>
		<title>実践Go言語(part8)</title>
		<link>http://golang.jp/2010/03/1235</link>
		<comments>http://golang.jp/2010/03/1235#comments</comments>
		<pubDate>Thu, 04 Mar 2010 09:00:57 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1235</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、8回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

初期化
初期化において、Go言語とCやC++言語では見かけ上それほど差がないように見えますが、G [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、8回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="initialization">初期化</h2>
<p>初期化において、Go言語とCやC++言語では見かけ上それほど差がないように見えますが、Go言語の初期化はより強力です。複合構造体は初期化を行いながら構築することが可能です。また異なるパッケージ間においてもオブジェクトの初期化順序は正しく取り扱われます。</p>
<h3 id="constants">定数</h3>
<p>Go言語における定数は、その名の通り「定数」です。定数はコンパイル時に作成されます。これは定数が関数内でローカルに定義されているときも同様です。ただし定数となり得るのは数値、文字列、論理値だけです。定数はコンパイル時に作成されるという制約上、コンパイラによって評価可能な定数式でなければなりません。たとえば<code>1&lt;&lt;3</code>は定数式ですが、<code>math.Sin(math.Pi/4)</code>は定数式ではありません。これは後者を評価するためには<code>math.Sin</code>の呼び出しが必要となるためです。</p>
<p>Go言語での定数の列挙には<code>iota</code>列挙子を使います。<code>iota</code>は式の一部となって、かつその式は暗黙的に繰り返すことができるので値の複雑なセットも簡単に作成することができます。</p>
<pre>type ByteSize float64
const (
    _ = iota  // 一番目の値はブランク識別子に代入して無視
    KB ByteSize = 1&lt;&lt;(10*iota)
    MB
    GB
    TB
    PB
    EB
    ZB
    YB
)</pre>
<p><code>String</code>のようなメソッドを型と結びつけることができるので、型の一部として上のような値を出力用に自前で自動フォーマットすることが可能になります。</p>
<pre>func (b ByteSize) String() string {
    switch {
    case b &gt;= YB:
        return fmt.Sprintf("%.2fYB", b/YB)
    case b &gt;= ZB:
        return fmt.Sprintf("%.2fZB", b/ZB)
    case b &gt;= EB:
        return fmt.Sprintf("%.2fEB", b/EB)
    case b &gt;= PB:
        return fmt.Sprintf("%.2fPB", b/PB)
    case b &gt;= TB:
        return fmt.Sprintf("%.2fTB", b/TB)
    case b &gt;= GB:
        return fmt.Sprintf("%.2fGB", b/GB)
    case b &gt;= MB:
        return fmt.Sprintf("%.2fMB", b/MB)
    case b &gt;= KB:
        return fmt.Sprintf("%.2fKB", b/KB)
    }
    return fmt.Sprintf("%.2fB", b)
}</pre>
<p>式<code>YB</code>の出力は<code>1.00YB</code>になり、<code>ByteSize(1e13)</code>の出力は<code>9.09TB</code>となります。</p>
<h3 id="variables">変数</h3>
<p>変数は、定数と同じように初期化することができますが、変数のイニシャライザは通常の式であり、実行時に評価されます。</p>
<pre>var (
    HOME = os.Getenv("HOME")
    USER = os.Getenv("USER")
    GOROOT = os.Getenv("GOROOT")
)</pre>
<h3 id="init">init関数</h3>
<p>最後になりますが、各ソースファイルにはそれぞれ必要に応じて、セットアップのために<code>init()</code>関数を定義することができます。ひとつだけ制約があり、初期化中にゴルーチンを起動することはできますが、初期化が完了するまで実行は開始しません。すなわち、初期化処理中に実行されるスレッドは常にひとつだけです。</p>
<p><code>init()</code>関数は、パッケージでインポートしている他のパッケージが初期化されたあと、パッケージ内で宣言されているすべての変数のイニシャライザが評価されたあとに呼び出されます。<code>init()</code>関数の一般的な使い方は、宣言としては記述できないような初期化処理を行うほか、処理の実行開始直前に、プログラムのステートの妥当性チェックおよびステートの修正を行います。</p>
<pre>func init() {
    if USER == "" {
        log.Exit("$USER not set")
    }
    if HOME == "" {
        HOME = "/usr/" + USER
    }
    if GOROOT == "" {
        GOROOT = HOME + "/go"
    }
    // GOROOTはコマンドラインから--gorrotフラグを指定することで上書き可能
    flag.StringVar(&amp;GOROOT, "goroot", GOROOT, "Go root directory")
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1235/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1235" />
	</item>
		<item>
		<title>実践Go言語(part7)</title>
		<link>http://golang.jp/2010/03/1228</link>
		<comments>http://golang.jp/2010/03/1228#comments</comments>
		<pubDate>Tue, 02 Mar 2010 07:17:20 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1228</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、7回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

データ
new()による割り当て
Go言語の基本的なメモリ割り当てには、new()とmake() [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、7回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="data">データ</h2>
<h3 id="allocation_new">new()による割り当て</h3>
<p>Go言語の基本的なメモリ割り当てには、<code>new()</code>と<code>make()</code>の2つがあります。これら2つはそれぞれ異なる働きをし、適用先の型も別となります。混乱させてしまうかもしれませんがルールは単純です。</p>
<p>まず<code>new()</code>について説明します。これは組み込み関数であり、他の言語における<code>new()</code>と基本的に同じです。<code>new(T)</code>は、型<code>T</code>の新しいアイテム用にゼロ化した領域を割り当て、そのアドレスである<code>*T</code>型の値を返します。Go言語風に言い換えると、<code>new(T)</code>が返す値は、新しく割り当てられた型<code>T</code>のゼロ値のポインタです。</p>
<p><code>new()</code>から返されるメモリはゼロ化されています。ゼロ化済みオブジェクトは、さらなる初期化を行わなくても使用できるため、こういったオブジェクトの準備に<code>new()</code>は便利です。すなわち、データ構造体の利用者が<code>new()</code>でそれを作成すると、すぐに使える状態となります。たとえば、<code>bytes.Buffer</code>のドキュメントには、「<code>Buffer</code>のゼロ値は、利用準備が整った空のバッファである。」と記述されています。同様に<code>sync.Mutex</code>には明示的なコンストラクタや<code>Init</code>メソッドは用意されていませんが、その代わりに<code>sync.Mutex</code>のゼロ値は、非ロック状態のミューテックスであることが定められています。</p>
<p>この便利なゼロ値は連鎖的に働きます。下の型宣言をみてください。</p>
<pre>type SyncedBuffer struct {
    lock    sync.Mutex
    buffer  bytes.Buffer
}</pre>
<p>この<code>SyncedBuffer</code>型の値もまた、割り当てや宣言を行うと同時に使用準備が整います。下のコードの変数<code>p</code>と<code>v</code>は、このままで正しく機能します。</p>
<pre>p := new(SyncedBuffer)  // type *SyncedBuffer
var v SyncedBuffer      // type  SyncedBuffer</pre>
<h3 id="composite_literals">コンストラクタと複合リテラル</h3>
<p>下の例は<code>os</code>パッケージからの抜粋です。この例のようにゼロ値では充分でなく、コンストラクタによる初期化が必要となることがあります。</p>
<pre>func NewFile(fd int, name string) *File {
    if fd &lt; 0 {
        return nil
    }
    f := new(File)
    f.fd = fd
    f.name = name
    f.dirinfo = nil
    f.nepipe = 0
    return f
}</pre>
<p>上のコードには冗長な部分が多く見られます。複合リテラルとは、実行する度に新しいインスタンスを生成する式であり、これを使うことで下のコードのように単純化することができます。</p>
<pre>func NewFile(fd int, name string) *File {
    if fd &lt; 0 {
        return nil
    }
    f := File{fd, name, nil, 0}
    return &amp;f
}</pre>
<p>このようにローカル変数のアドレスを返しても問題ありません。関数から戻ったあとも、変数に割り当てたメモリは生き残ります。複合リテラルのアドレスを取得したときは、実行する度に新しいインスタンスが割り当てられる仕様なので、最後の2行を次のようにまとめることができます。</p>
<pre>    return &amp;File{fd, name, nil, 0}</pre>
<p>複合リテラルでは、すべてのフィールドを順番通りに記述しなければなりません。ただし明示的に「フィールド:値」の組み合わせで要素にラベルをつけたときは、イニシャライザは順序通りである必要はなく、また指定しなかった要素には、その型のゼロ値がセットされます。すなわち次のように書き換えられます。</p>
<pre>    return &amp;File{fd: fd, name: name}</pre>
<p>特殊なケースとして、複合リテラルがひとつもフィールドを含まないときは、その型のゼロ値が作られます。すなわち、式<code>new(File)</code>と<code>&amp;File{}</code>は等価です。</p>
<p>また複合リテラルでは、フィールドのラベルをインデックスまたはマップのキーとみなして、配列、スライス、マップを作成することもできます。次の例において、<code>Enone</code>、<code>Eio</code>、<code>Einval</code>がそれぞれ個別の変数でありさえすれば、その値に関わらず初期化は成功します。</p>
<pre>a := [...]string   {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
s := []string      {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
m := map[int]string{Enone: "no error", Eio: "Eio", Einval: "invalid argument"}</pre>
<h3 id="allocation_make">make()による割り当て</h3>
<p>割り当てに話を戻します。組み込み関数<code>make(T, </code><em>args</em><code>)</code>は、<code>new(T)</code>とは使用目的が異なります。<code>make</code>で割り当てできるのはスライス、マップ、チャネルだけであり、初期化された、すなわちゼロ値でない<code>T</code>型(<code>*T</code>でない)の値を返します。<code>make</code>と<code>new</code>を使い分ける理由は、これらの3つの型が隠蔽されたデータ構造への参照であり、このデータ構造が使用前に初期化されている必要があるためです。スライスを例にとると、スライスはデータ(配列内)へのポインタ、長さ、キャパシティという３つの情報から構成されており、それらの情報が初期化されるまではスライスの値は<code>nil</code>です。<code>make</code>はスライス、マップ、チャネルの内部データ構造を初期化し、使用可能となるよう値を準備します。下は、<code>make</code>の例です。</p>
<pre>make([]int, 10, 100)</pre>
<p>この例では、100個のintを持つ配列を割り当てたあと、その配列の先頭から10個目までの要素を示す、長さが10でキャパシティ100のスライス構造を作成します。(スライス作成時、キャパシティは省略可能です。詳細はスライスに関するセクションを参照ください。)これに対して、<code>new([]int)</code>は新しくメモリを割り当て、ゼロ化したスライス構造のポインタを返します。つまりこれは<code>nil</code>スライス値へのポインタです。</p>
<p>下は、<code>new()</code>と<code>make()</code>の違いを例示したものです。</p>
<pre>var p *[]int = new([]int)       // スライス構造の割り当て(*p == nil)。あまり使わない。
var v  []int = make([]int, 100) // vは100個のintを持つ配列への参照

// 必要以上に複雑な書き方
var p *[]int = new([]int)
*p = make([]int, 100, 100)

// 一般的な書き方
v := make([]int, 100)</pre>
<p>覚えておいていただきたいことは、<code>make()</code>が適用可能なのはマップ、スライス、チャネルだけであり、返されるのはポインタではないことです。ポインタが必要であれば<code>new()</code>で割り当ててください。</p>
<h3 id="arrays">配列</h3>
<p>配列はメモリ配置を厳密に指定したいときや、ときにはメモリ割り当てを回避したいときに役立ちますが、配列の主な役割は、次セクションの主題であるスライスから参照されることです。そのスライスについて説明する前に基礎知識として、配列について2、3説明しておきます。</p>
<p>Go言語とC言語では配列の動作に大きな違いがあります。Go言語では次のように振舞います。</p>
<ul>
<li> 配列は値です。ある配列を他へ代入するとすべての要素がコピーされます。</li>
<li> すなわち関数に配列を渡すと、関数側ではポインタではなく、その配列のコピーを受け取ります。</li>
<li> 配列のサイズは型の一部です。<code>[10]int</code>と<code>[20]int</code>は異なる型です。</li>
</ul>
<p>値として扱うと有用なこともありますが、高コストでもあるため、C言語のような動作と効率が必要であれば、配列へのポインタを関数に渡すことも可能です。</p>
<pre>func Sum(a *[3]float) (sum float) {
    for _, v := range *a {
        sum += v
    }
    return
}

array := [...]float{7.0, 8.5, 9.1}
x := Sum(&amp;array)  // 注：明示的にアドレス演算子を使用</pre>
<p>しかし、これはGo言語では一般的ではなく、通常はスライスを使用します。</p>
<h3 id="slices">スライス</h3>
<p>スライスは配列をラップして、データ列に対しより普遍的かつ効果的で使い易いインタフェースを提供します。変換行列のような明らかに多次元のデータ構造を扱う場合を除いて、配列を扱うGo言語のプログラムでは、配列そのままではなくスライスが多用されます。</p>
<p>スライスは参照型です。すなわちスライスを別のスライスに代入したときは、双方が同じ配列を参照します。たとえば関数がスライスを引数として取るとき、関数内でスライスの要素に変更を加えると、ポインタ渡しのように関数の呼び元からも変更内容が参照できます。ゆえに<code>Read</code>関数では、引数としてポインタと個数を受け取る代わりに、スライスを受け取ることが可能となります。このときスライスが持つ長さ情報は、読み込むべきデータの上限となります。下は、<code>os</code>パッケージの<code>File</code>型の<code>Read</code>メソッドのシグネチャです。</p>
<pre>func (file *File) Read(buf []byte) (n int, err os.Error)</pre>
<p>このメソッドは読み込んだバイト数と、エラーがあればエラー値を返します。ある大きなバッファ<code>buf</code>から先頭32バイトを読み込むためには、次のようにバッファをスライスしてください。※この「スライス」という言葉は名詞ではなく動詞です。</p>
<pre>    n, err := f.Read(buf[0:32])</pre>
<p>こういったスライスの使い方は一般的かつ効率的です。実際のところ、あまり効率を考慮に入れなければ、下のコードでも同様にバッファの先頭32バイトを読み込めます。</p>
<pre>    var n int
    var err os.Error
    for i := 0; i &lt; 32; i++ {
        nbytes, e := f.Read(buf[i:i+1])  // 1バイト読み込み
        if nbytes == 0 || e != nil {
            err = e
            break
        }
        n += nbytes
    }</pre>
<p>スライスが持つ長さ情報は、その参照先配列の範囲内であれば変更することができます。(試しにスライスを同じスライスに代入し直してみてください。) スライスのキャパシティは組み込み関数の<code>cap</code>で参照できます。キャパシティとはスライスが扱える長さの上限値です。<br />
下はスライスにデータを追加する関数です。この関数ではデータの長さがキャパシティを超えるときは、スライスは再割り当てされ、結果得られたスライスが関数から返されます。<code>nil</code>スライスが関数に与えられたときには、仕様上<code>nil</code>スライスが<code>len</code>、<code>cap</code>ともに0を返すことを利用しています。</p>
<pre>func Append(slice, data[]byte) []byte {
    l := len(slice)
    if l + len(data) &gt; cap(slice) {  // reallocate
        // 再利用を考慮し、必要なサイズの倍、割り付ける
        newSlice := make([]byte, (l+len(data))*2)
        // Copy data (could use bytes.Copy()).
        for i, c := range slice {
            newSlice[i] = c
        }
        slice = newSlice
    }
    slice = slice[0:l+len(data)]
    for i, c := range data {
        slice[l+i] = c
    }
    return slice
}</pre>
<p><code>Append</code>では<code>slice</code>の要素を変更していますが、スライス自体(ランタイムデータ構造がポインタ、長さ、キャパシティを保持している)は値渡しされているため、処理を終えたあと関数からスライスを返す必要があります。</p>
<h3 id="maps">マップ</h3>
<p>マップは、異なる型の値を結びつける便利で強力な組み込みデータ構造です。マップのキーには、イコール演算子が定められていればどんな型(例えば整数、浮動小数、文字列、ポインタ、動的な型がイコールをサポートするのであればインタフェースさえ)でも使えます。ですが構造体、配列、スライスにはイコールが定義されていないため、マップのキーとして使用することはできません。スライスと同じくマップもまた参照型であるため、マップを関数に渡し、その関数内でマップの内容に変更を加えると、変更内容は呼び出し元からも参照可能です。</p>
<p>複合リテラル構文を使い、キーと値をコロン区切りで指定することでマップを作成できるので、作成と同時に初期化が簡単に行えます。</p>
<pre>var timeZone = map[string] int {
    "UTC":  0*60*60,
    "EST": -5*60*60,
    "CST": -6*60*60,
    "MST": -7*60*60,
    "PST": -8*60*60,
}</pre>
<p>マップへの値の設定と取得は、配列の操作と構文的に似通っていますが、インデックスが整数である必要がない点で異なります。マップ内に存在しないキーを使って、マップから値を取得しようとするとプログラムがクラッシュする要因と成り得るので、これを回避するため下のように複数代入式を使ってください。</p>
<pre>var seconds int
var ok bool
seconds, ok = timeZone[tz]</pre>
<p>これは見たままですが、「カンマok」慣用句と呼ばれています。この例では、<code>tz</code>が存在すれば、<code>seconds</code>に適切な値がセットされ、<code>ok</code>の値は真となります。存在しなければ、<code>seconds</code>にはゼロがセットされ、<code>ok</code>の値は偽となります。下はこれを利用した関数です。</p>
<pre>func offset(tz string) int {
    if seconds, ok := timeZone[tz]; ok {
        return seconds
    }
    log.Stderr("unknown time zone", tz)
    return 0
}</pre>
<p>マップ内に値が存在するか調べたいとき、値自体の取得が不要であればブランク識別子(ただのアンダーライン(_))を使うことができます。ブランク識別子を使うとどんな型の値でも代入または宣言することができ、値を他に影響およぼすことなく破棄することができます。マップ内の存在チェックをするときは、次のように本来は値が返される変数の代わりにブランク識別子を指定してください。</p>
<pre>_, present := timeZone[tz]</pre>
<p>マップから登録を削除するには、代入方向を変えて複数代入式の右側に論理値を指定してください。この論理値の値が偽のとき登録が削除されます。このときマップ内にキーが存在しなくても問題ありません。</p>
<pre>timeZone["PDT"] = 0, false  // 標準時に</pre>
<h3 id="printing">出力</h3>
<p>Go言語におけるフォーマット出力は、C言語の<code>printf</code>群のスタイルと類似していますが、より高機能・多機能です。これら関数は<code>fmt</code>パッケージ内で定義されています。先頭一文字は大文字となっており、<code>fmt.Printf</code>、<code>fmt.Fprintf</code>、<code>fmt.Sprintf</code>などが用意されています。文字列関数(<code>Sprintf</code>など)は、指定したバッファに文字列を格納するのではなく、新しい文字列を返します。</p>
<p>フォーマット文字列の指定は必要ではありません。各<code>Printf</code>、<code>Fprintf</code>、<code>Sprintf</code>にはそれぞれ他にペアとなる関数、例えば<code>Print</code>と<code>Println</code>が用意されています。これらの関数はフォーマット文字列をとらず、代わりに引数ごとにデフォルトフォーマットを生成します。<code>ln</code>版では、引数の間に両引数とも文字列でないときだけ空白を挿入し、出力の後ろに改行を付加します。[訳注：実際試したところ、非<code>ln</code>版のときは引数がともに文字列でないときだけ引数間に空白が挿入されるのに対し、<code>ln</code>版のときは常に空白が挿入されるようです] 下の例では、各行はいずれも同じ内容を出力します。</p>
<pre>fmt.Printf("Hello %d\n", 23)
fmt.Fprint(os.Stdout, "Hello ", 23, "\n")
fmt.Println(fmt.Sprint("Hello ", 23))</pre>
<p>チュートリアルでも解説したように、<code>fmt.Fprint</code>とそれに関連する関数は、一番目の引数に<code>io.Writer</code>インタフェースを実装していればどんなオブジェクトでも指定可能です。 よく使われるのは、お馴染みの変数<code>os.Stdou</code>と<code>os.Stderr</code>です。</p>
<p>ここからC言語との違いが現れます。まず、<code>%d</code>のような数値フォーマットでは、フラグによる符号やサイズの指定は行いません。その代わりに出力ルーチンは、引数の型を参照して値の属性を決定します。</p>
<pre>var x uint64 = 1&lt;&lt;64 - 1
fmt.Printf("%d %x; %d %x\n", x, x, int64(x), int64(x))</pre>
<p>これの出力結果です。</p>
<pre>18446744073709551615 ffffffffffffffff; -1 -1</pre>
<p>例えば整数値を10進表記で出力するようなデフォルトの変換でよければ、どんなケースにも対応可能なフォーマット<code>%v</code>を使うことができます。このとき出力される内容は、<code>Print</code>と<code>Println</code>の出力結果と全く同じです。さらにこのフォーマットは、配列、構造体、マップなどどんな値でも出力することができます。下は、前のセクションで定義したタイムゾーンマップを出力するステートメントです。</p>
<pre>fmt.Printf("%v\n", timeZone)  // fmt.Println(timeZone)としても同じ</pre>
<p>これの出力結果です。</p>
<pre>map[CST:-21600 PST:-28800 EST:-18000 UTC:0 MST:-25200]</pre>
<p>マップの出力では、キーの出力は当然ながら順不同となります。<br />
構造体を出力するとき、限定フォーマット<code>%+v</code>を使うと構造体の各フィールドに対してフィールド名も出力されます。また、代替フォーマット<code>%#v</code>を使うとどんな値でも完全なGo言語の構文形式で出力されます。</p>
<pre>type T struct {
    a int
    b float
    c string
}
t := &amp;T{ 7, -2.35, "abc\tdef" }
fmt.Printf("%v\n", t)
fmt.Printf("%+v\n", t)
fmt.Printf("%#v\n", t)
fmt.Printf("%#v\n", timeZone)</pre>
<p>これらの出力結果です。(アンパサンドに注意)</p>
<pre>&amp;{7 -2.35 abc   def}
&amp;{a:7 b:-2.35 c:abc     def}
&amp;main.T{a:7, b:-2.35, c:"abc\tdef"}
map[string] int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200}</pre>
<p>引用符付き文字列の出力も、<code>string</code>または<code>[]byte</code>型の値に対して<code>%q</code>を使えば可能です。(代替フォーマット<code>%#q</code>では、可能であればバッククォートを使います。) また<code>%x</code>を文字列またはバイト配列に対して適用したときは、整数に適用したときと同様に、長い16進数文字列を出力します。このときフォーマットにスペースを入れると(<code>% x</code>)、バイト間にスペースが出力されます。</p>
<p>もう一つの便利なフォーマットは<code>%T</code>です。これは値の型を出力します。</p>
<pre>fmt.Printf("%T\n", timeZone)</pre>
<p>これの出力結果です。</p>
<pre>map[string] int</pre>
<p>自作の型でデフォルトのフォーマット処理を制御したければ、必要なことはその型にメソッド<code>String() string</code>を定義するだけです。下は先ほどの型<code>T</code>に実装してみた例です。</p>
<pre>func (t *T) String() string {
    return fmt.Sprintf("%d/%g/%q", t.a, t.b, t.c)
}
fmt.Printf("%v\n", t)</pre>
<p>これのフォーマット出力結果です。</p>
<pre>7/-2.35/"abc\tdef"</pre>
<p>自作の<code>String()</code>メソッドは<code>Sprintf</code>からも呼び出されます。これは出力ルーチンが完全にリエントラント(再入可能)かつ再帰的に呼び出されるためです。もう少し手を加えて、出力ルーチンが受け取った引数を、同様の別ルーチンにそのまま渡すことも可能です。<code>Printf</code>のシグネチャの最後の引数には&#8230;型が使われているため、フォーマット指定以降には、いくつでもパラメータを指定できます。</p>
<pre>func Printf(format string, v ...) (n int, errno os.Error) {</pre>
<p><code>Printf</code>関数内の変数<code>v</code>は、別の出力ルーチンに渡すことも可能です。下は、以前使用した関数<code>log.Stderr</code>の実装です。ここでは、実際にフォーマット処理を行うために、<code>fmt.Sprintln</code>に引数をそのまま渡しています。</p>
<pre>// Stderrは標準出力にログを簡単に出力するヘルパー関数です。Fprint(os.Stderr)と似ています。
func Stderr(v ...) {
    stderr.Output(2, fmt.Sprintln(v))  // Outputはパラメータ (int, string)を取る
}</pre>
<p>ここで説明した範囲は出力機能のほんの一部です。より詳しい説明はパッケージ<code>fmt</code>の<code>godoc</code>ドキュメントを参照ください。</p>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/03/1228/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/03/1228" />
	</item>
		<item>
		<title>実践Go言語(part6)</title>
		<link>http://golang.jp/2010/02/1210</link>
		<comments>http://golang.jp/2010/02/1210#comments</comments>
		<pubDate>Mon, 08 Feb 2010 06:36:31 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1210</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、6回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

関数
複数の戻り値
Go言語の目新しい特徴のひとつは、関数およびメソッドが複数の値を返せることで [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、6回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="functions">関数</h2>
<h3 id="multiple-returns">複数の戻り値</h3>
<p>Go言語の目新しい特徴のひとつは、関数およびメソッドが複数の値を返せることです。これは、C言語のプログラムで扱いにくかった、受信エラー(<code>EOF</code>を表す<code>-1</code>など)や引数の値の変更などを改善します。</p>
<p>C言語で書き込みエラーが起きたときは、マイナス値を返すことにより通知され、共用の変数にエラーコードが格納されます。Go言語では<code>Write</code>は書き込みデータ数とエラーを別々に返すことができます。つまり次のような情報を得ることができます。「何バイトか書き込めましたが、デバイスが一杯になったので一部書き込めませんでした。」</p>
<p><code>os</code>パッケージの<code>*File.Write</code>のシグネチャは次のように定義されています。</p>
<pre>func (file *File) Write(b []byte) (n int, err Error)</pre>
<p>シグネチャが示すとおりに、このメソッドは書き込んだバイト数を返すとともに、<code>n</code> <code>!=</code> <code>len(b)</code>のとき非nilの<code>Error</code>を返します。これは一般的な書き方です。その他の例は、エラーハンドリングに関するセクションを参照ください。</p>
<p>同様のアプローチにより、戻り値に参照パラメータを模してポインタを返す必要がなくなります。次の関数は、バイト配列の指定位置から数値を取り出し、その値と次の位置を返す単純な関数です。</p>
<pre>func nextInt(b []byte, i int) (int, int) {
    for ; i &lt; len(b) &amp;&amp; !isDigit(b[i]); i++ {
    }
    x := 0
    for ; i &lt; len(b) &amp;&amp; isDigit(b[i]); i++ {
        x = x*10 + int(b[i])-'0'
    }
    return x, i
}</pre>
<p>この関数は次のようにして、入力配列から数値を取り出すために利用できます。</p>
<pre>    for i := 0; i &lt; len(a); {
        x, i = nextInt(a, i)
        fmt.Println(x)
    }</pre>
<h3 id="named-results">名前付き結果パラメータ</h3>
<p>Go言語の、戻り／結果「パラメータ」には、名前をつけることができ、引数パラメータのように通常の変数として扱うことができます。名前が付けられていると、関数が呼び出されたときにその型のゼロ値で初期化されます。引数を持たない<code>return</code>ステートメントを実行したときは、その時点で結果パラメータに格納されている値が、戻り値として使われます。</p>
<p>名前は必ずしも必要ではありませんが、名前をつけることでコードをより簡潔にすることができます。これは資料としても役立ちます。前出の<code>nextInt</code>関数の結果パラメータに名前を付けると、返された<code>int</code>値がそれぞれ何を示しているか明確になります。</p>
<pre>func nextInt(b []byte, pos int) (value, nextPos int) {</pre>
<p>名前付きの結果パラメータは、初期化が行われた上で、パラメータなしのreturnと結びつけられるので、明確になるだけでなくシンプルになります。下は、この仕組みをうまく使った<code>io.ReadFull</code>の例です。</p>
<pre>func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
    for len(buf) &gt; 0 &amp;&amp; err == nil {
        var nr int
        nr, err = r.Read(buf)
        n += nr
        buf = buf[nr:len(buf)]
    }
    return
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/02/1210/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/02/1210" />
	</item>
		<item>
		<title>実践Go言語(part5)</title>
		<link>http://golang.jp/2010/02/1170</link>
		<comments>http://golang.jp/2010/02/1170#comments</comments>
		<pubDate>Thu, 04 Feb 2010 06:12:01 +0000</pubDate>
		<dc:creator>noboru</dc:creator>
				<category><![CDATA[ドキュメント]]></category>
		<category><![CDATA[Effective Go]]></category>
		<category><![CDATA[実践Go言語]]></category>

		<guid isPermaLink="false">http://golang.jp/?p=1170</guid>
		<description><![CDATA[実践Go言語(Effective Go)の翻訳、5回目です。
前回までの訳は実践Go言語[日本語訳]にまとめてあります。

制御構造
Go言語の制御構造は、C言語の制御構造と似通っていますが、大きく異なる点があります。ル [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/doc/effective_go.html" target="_blank">実践Go言語(Effective Go)</a>の翻訳、5回目です。<br />
前回までの訳は<a href="/effective_go">実践Go言語[日本語訳]</a>にまとめてあります。</p>
<hr />
<h2 id="control-structures">制御構造</h2>
<p>Go言語の制御構造は、C言語の制御構造と似通っていますが、大きく異なる点があります。ループには<code>do</code>や<code>while</code>はなく、若干改良された<code>for</code>ループだけです。<code>switch</code>はより柔軟になっています。<code>if</code>と<code>switch</code>はオプションとして<code>for</code>のように初期化ステートメントを受け入れます。また、新しい制御構造として、型<code>switch</code>、および多重通信を取り扱える<code>select</code>があります。文法も若干異なっており、丸括弧()は不要ですが、本体部は波括弧で区切られていなければなりません。</p>
<h3 id="if">if</h3>
<p>下はGo言語における単純な<code>if</code>ステートメントです。</p>
<pre>if x &gt; 0 {
    return y
}</pre>
<p>波括弧{}を必須にしたことにより、複数行に渡る<code>if</code>ステートメントの記述が見やすくなりました。これは特に、<code>return</code>や<code>break</code>のような制御ステートメントを含むときには優れた書き方です。</p>
<p><code>if</code>と<code>switch</code>には初期化ステートメントを記述できるため、そこでローカル変数の準備を行うのが一般的です。</p>
<pre>if err := file.Chmod(0664); err != nil {
    log.Stderr(err)
    return err
}</pre>
<p id="else">Go言語のライブラリ内で良く見られる書き方ですが、<code>if</code>ステートメントから次のステートメントへ制御が移らないとき(すなわち、<code>break</code>、<code>continue</code>、<code>goto</code>、<code>return</code>のいずれかで<code>if</code>の本体から抜けるとき）は、不要な<code>else</code>は省略します。</p>
<pre>f, err := os.Open(name, os.O_RDONLY, 0)
if err != nil {
    return err
}
codeUsing(f)</pre>
<p>下の例は、一連のエラー判定を必要とするよく出会う状況です。処理が成功と判断されたときは、エラー処理はスキップし、処理が下方へと流れていくので読みやすいコードとなっています。エラーのときは<code>return</code>ステートメントで抜けてしまうため、<code>else</code>ステートメントは必要ありません。</p>
<pre>f, err := os.Open(name, os.O_RDONLY, 0)
if err != nil {
    return err
}
d, err := f.Stat()
if err != nil {
    return err
}
codeUsing(f, d)</pre>
<h3 id="for">for</h3>
<p>Go言語の<code>for</code>ループは、C言語の<code>for</code>と似てはいますが、同じではありません。Go言語の<code>for</code>ループは、C言語の<code>for</code>と<code>while</code>ループを兼ねていますが、<code>do-while</code>ループに相当するものはありません。<code>for</code>ループには３つの形式がありますが、セミコロンを使うのはそのうちひとつだけです。</p>
<pre>// Cのforに相当する形式
for init; condition; post { }

// Cのwhileに相当する形式
for condition { }

// Cのfor(;;)に相当する形式
for { }</pre>
<p>省略形式による変数の宣言(<code>:=</code>)を使うと、インデックス変数の宣言が容易です。</p>
<pre>sum := 0
for i := 0; i &lt; 10; i++ {
    sum += i
}</pre>
<p>配列、スライス、文字列、マップの内容、もしくはチャネルから読み込んだデータをループさせるときは、<code>range</code>節でループを制御することができます。</p>
<pre>var m map[string]int
sum := 0
for _, value := range m {  // キーは使われません
    sum += value
}</pre>
<p>文字列を扱うときの<code>range</code>はより高機能で、UTF-8エンコードでユニコードの各文字を取り出します。このとき不正なエンコーディングあると、1バイトスキップした上で置換ルーン(Unicode replacement character U+FFFD)として扱います。下はループの例です。</p>
<pre>for pos, char := range "日本語" {
    fmt.Printf("character %c starts at byte position %d\n", char, pos)
}</pre>
<p>次が出力されます。</p>
<pre>character 日 starts at byte position 0
character 本 starts at byte position 3
character 語 starts at byte position 6</pre>
<p>最後になりますが、Go言語にはカンマ演算子がなく、また<code>++</code>と<code>--</code>は式ではなくステートメントです。<code>for</code>で複数の変数を回したいときは、下のように同時代入を使わなければなりません。</p>
<pre>// aを逆に並び替える
for i, j := 0, len(a)-1; i &lt; j; i, j = i+1, j-1 {
    a[i], a[j] = a[j], a[i]
}</pre>
<h3 id="switch">switch</h3>
<p>Go言語の<code>switch</code>は、C言語より多機能です。<code>switch</code>の式は、定数や整数である必要はありません。一致するものが見つかるまで、<code>case</code>を上から下まで評価していきます。<code>switch</code>が式を伴わないときは、式の値が<code>true</code>となる<code>case</code>にマッチします。これを利用して<code>switch</code>を使って<code>if</code>-<code>else</code>-<code>if</code>-<code>else</code>チェーンを書くことができます。これは慣用的な書き方です。</p>
<pre>func unhex(c byte) byte {
    switch {
    case '0' &lt;= c &amp;&amp; c &lt;= '9':
        return c - '0'
    case 'a' &lt;= c &amp;&amp; c &lt;= 'f':
        return c - 'a' + 10
    case 'A' &lt;= c &amp;&amp; c &lt;= 'F':
        return c - 'A' + 10
    }
    return 0
}</pre>
<p><code>case</code>から直下の<code>case</code>へと処理が自動的に移ることはありませんが、<code>case</code>にはカンマで区切ったリストを指定できます。</p>
<pre>func shouldEscape(c byte) bool {
    switch c {
    case ' ', '?', '&amp;', '=', '#', '+', '%':
        return true
    }
    return false
}</pre>
<p>下は、2つの<code>switch</code>ステートメントを使ったバイト配列の比較ルーチンです。</p>
<pre>// Compare は2つのバイト配列を辞書的に比較して整数を返します。
// 結果は、a == bのとき0、a &lt; bのとき-1、a &gt; bのとき+1
func Compare(a, b []byte) int {
    for i := 0; i &lt; len(a) &amp;&amp; i &lt; len(b); i++ {
        switch {
        case a[i] &gt; b[i]:
            return 1
        case a[i] &lt; b[i]:
            return -1
        }
    }
    switch {
    case len(a) &lt; len(b):
        return -1
    case len(a) &gt; len(b):
        return 1
    }
    return 0
}</pre>
<p><code>switch</code>は、インタフェース変数の動的な型を見つけるために用いることもできます。その型<code>switch</code>には、型アサーションの構文を使って丸括弧()の中にキーワード<code>"type"</code>と書きます。<code>switch</code>の式で変数を宣言したとき、その変数は各<code>case</code>節において適切な型となります。</p>
<pre>switch t := interfaceValue.(type) {
default:
    fmt.Printf("unexpected type %T", t)  // %T は型を出力する
case bool:
    fmt.Printf("boolean %t\n", t)
case int:
    fmt.Printf("integer %d\n", t)
case *bool:
    fmt.Printf("pointer to boolean %t\n", *t)
case *int:
    fmt.Printf("pointer to integer %d\n", *t)
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://golang.jp/2010/02/1170/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://golang.jp/2010/02/1170" />
	</item>
	</channel>
</rss>
