SSブログ

bytes.Bufferの実装の変更 [golang]

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

  • 作者: Alan A.A. Donovan
  • 出版社/メーカー: 丸善出版
  • 発売日: 2016/06/20
  • メディア: 単行本(ソフトカバー)

『プログラミング言語Go』の「6.6 カプセル化」でbytes.Bufferに関して次のような記述があります(193ページ)。
例として、bytes.Buffer型を考えてみてください。 この型は非常に短い文字列を蓄積するために頻繁に使われます。したがって、そのようによくある場面でのメモリ割り当てを避けるために、そのオブジェクト内に少し余分な領域を確保するのは有益な最適化です。 Bufferは構造体型なので、その領域は大文字で始まっていない名前を持つ[64]byte型の追加のフィールドの形式になります。このフィールドが追加されたとき、それは公開されなかったので、Bufferを使うbytesパッケージの外部のクライアントは、改善された性能を除いたどの変更にも気づきませんでした。
実際に、Go 1.11まではこの記述にあるような実装なのですが、次のGo 1.12ではこの[64]byte型の追加のフィールドは削除されるようです。修正のコミットは、こちらです。

コメント(0) 

『Java Puzzlers』とGo言語(2) [golang]

Java Puzzlers 罠、落とし穴、コーナーケース

Java Puzzlers 罠、落とし穴、コーナーケース

  • 作者: ジョシュア・ブロック
  • 出版社/メーカー: ピアソン・エデュケーション
  • 発売日: 2005/11/14
  • メディア: 大型本
パズル3: 長除法(Long Division)

このパズルは、2 つのlong 値を割るプログラムに関することなので、LongDivision と呼ばれます。被除数は一日が何マイクロ秒であるかを表し、除数は一日が何ミリ秒であるかを表しています。このプログラムは、何を表示しますか?
public class LongDivision {
    public static void main(String[] args) {
        final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
        final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
        System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
    }
}
このプログラムの実行結果は、5です。その理由は、Javaではint型(上記の数値リテラルはすべてint)から構成される式の演算結果の型はintなので、上記のMICROS_PER_DAYへの代入の右辺の式の計算結果はintに収まらずにオーバーフローが発生しているからです。その結果、小さな値となっており、実行結果が5なのです。

単純にGo言語で書いたコードは次のようになります(対比しやすいように、Go言語の命名規則には従っていません)。
package main

import "fmt"

func main() {
    var MICROS_PER_DAY int64 = 24 * 60 * 60 * 1000 * 1000
    var MILLIS_PER_DAY int64 = 24 * 60 * 60 * 1000
    fmt.Println(MICROS_PER_DAY / MILLIS_PER_DAY)
}
このコードの実行結果は、1000です。その理由は、右辺の式に書かれているものはすべて定数つまり「型付けなし整数」であるため、式の演算はコンパイル時に計算されます。そして、その計算結果の値も「型付けなし整数」なのです。

「型付けなし整数」の値は、型がある変数(上記の場合、int64MICROS_PER_DAY)への代入において、変数の型(int64)の取り得る値の範囲に収まれば、コンパイルされます。収まらなければ、コンパイルエラーです。

コメント(0) 

『Java Puzzlers』とGo言語(1) [golang]

先週の金曜日のGo言語研修が終わって、懇親会(会社の食堂)まで時間があったので、『Java Puzzlers』をやってみました。

Java Puzzlers 罠、落とし穴、コーナーケース

Java Puzzlers 罠、落とし穴、コーナーケース

  • 作者: ジョシュア・ブロック
  • 出版社/メーカー: ピアソン・エデュケーション
  • 発売日: 2005/11/14
  • メディア: 大型本

もう12年前の本で、現在は絶版となっています。発売された時に、日本でJavaOneが開催されていて、印刷されたばかりのこの本が販売された頃が懐かしいです。

ところで、Javaではパズルになるものが、Go言語ではそもそもコンパイルエラーになるものが多いです。その理由の一つは、異なる整数型の混合計算をGo言語が許さないことです。初めてGo言語に触れると、その点がちょっと煩わしく感じます。でも、パズルをGo言語で書くとどうなるかを知ると、言語の違いが分かってきて面白いです。
パズル2: 変革の時(Time for a Change)

次の文章問題を考えてみてください。
トムは、$1.10 するスパークプラグを購入するために自動車部品店に行きますが、財布の中にあるのは2 ドル紙幣ばかりです。2 ドル紙幣でスパークプラグの代金を支払ったとしたら、彼は、お釣りをいくら貰うでしょうか。

この文章問題を解こうとしているのが、次のプログラムです。このプログラムは、何を表示しますか?
public class Change {
    public static void main(String args[]) {
        System.out.println(2.00 - 1.10);
    }   
}
これを実行すると結果は、0.8999999999999999となります。その理由は、1.10を浮動小数点数では正確に表現できないからです。

Go言語で同じコードを書くと次のようになります。
package main

import "fmt"

func main() {
    fmt.Println(2.00 - 1.10)
}
そして、実行結果は、0.9です。なぜ、Go言語でこうなってしまうのでしょうか?

それは、2.001.10の扱いの違いです。Go言語では、それらは「型付けなし(untyped)浮動小数点数」です。そして、Printlnの引数の式は定数リテラルの演算なので、コンパイル時に定数として計算されます。この定数計算に関しては、Go言語では言語仕様ですべのGo言語の実装に対して、次のように高い精度を要求しています。

Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed binary exponent of at least 16 bits.
しかし、いくら高い精度でもっても、正確には表現できないはずです。そこで、言語仕様では次の条件が付加されています。
Round to the nearest representable constant if unable to represent a floating-point or complex constant due to limits on precision.
つまり、定数計算の結果は、表現可能な最も近い値の定数となるのです。

もちろん、定数ではないfloat64の変数に代入してから計算すると、0.9にはなりません。
package main

import "fmt"

func main() {
    var x, y float64 = 2.00, 1.10
    fmt.Println(x - y)
}
このコードの実行結果は、0.8999999999999999です。

型付けなし定数については、『プログラミング言語Go』の「3.6.2 型付けなし定数」(p.87)でも説明されていますが、上記の丸めについては書かれていません。

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

  • 作者: Alan A.A. Donovan
  • 出版社/メーカー: 丸善出版
  • 発売日: 2016/06/20
  • メディア: 単行本(ソフトカバー)


コメント(0) 

内容補足:『プログラミング言語Go』 [golang]

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

  • 作者: Alan A.A. Donovan
  • 出版社/メーカー: 丸善出版
  • 発売日: 2016/06/20
  • メディア: 単行本(ソフトカバー)

すでに本になってしまったので訳注を追加することはできませんが、補足として書いておきたいと思います。

7.8節「errorインタフェース」(p.226)に次の記述があります。
error を作成する最も簡単な方法は、指定されたエラーメッセージに関する新たなerror を返す errors.New を呼び出すことです。errors パッケージ全体は、次の4 行しかありません。
    package errors

    func New(text string) error { return &errorString{text} }

    type errorString struct { text string }

    func (e *errorString) Error() string { return e.text }
errorStringの基底型は、その表現を不注意な(あるいは意図的な)更新から保護するために、文字列ではなく構造体です。(以下省略)
文字列は不変(immutable)なのですが、リフレクションを使用すると書き直すことができます。リフレクションを使用して文字列を書き直したコード例はこちらです。

一方、構造体の非公開なフィールドはリフレクションを使用して書き換えることはできません。そのことは、p.396に記述されています。
Display をos.Stdout へ適用した場合、Unix ライクなプラットフォーム上のos.File 構造体のfd int フィールドといった、通常の言語規則に従えばアクセスできない構造体の非公開なフィールドの値をリフレクションが読み出せることが分かります。しかし、リフレクションでそのような値を変更することはできません。

(コード例は省略)

アドレス化可能なreflect.Value は、走査によって構造体の非公開のフィールドが得られたかどうかを記録しており、そうであれば変更を許しません。


『プログラミング言語Go』刊行記念トークセッション [golang]

スクリーンショット 2016-06-20 4.36.33.png


7月6日(水)に開催されるGoogleのソフトウェアエンジニアである鵜飼文敏氏とのトークセッションです。鵜飼文敏氏からは、書籍の帯のメッセージをいただきました。鵜飼氏は、次の本の監訳をされていますし、『Binary Hacks ―ハッカー秘伝のテクニック100選』を共著で執筆されています。

Go言語によるWebアプリケーション開発

Go言語によるWebアプリケーション開発

  • 作者: Mat Ryer
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2016/01/22
  • メディア: 大型本

無料ではなく入場料はドリンク付きで1000円ですが、奮ってご参加ください。ジュンク堂のイベントページは、こちらです(事前予約が必要です)。

当日は、著者アラン・ドノバンとブライアン・カーニハンのサインが書かれた日本語版が展示される予定です。

第1章公開:『プログラミング言語Go』 [golang]

プログラミング言語Go

プログラミング言語Go

  • 作者: Alan A.A. Donovan
  • 出版社/メーカー: 丸善出版
  • 発売日: 2016/06/20
  • メディア: 単行本(ソフトカバー)

発売に先行して、以下の内容を含むPDFが公開されました。PDFはこちらです。
  • 日本語版によせて
  • 目次
  • まえがき
  • 第1章 チュートリアル

【追記】6月10日に出版社から届きました。
13442446_1207804605905481_4671615962188119945_o.jpg


『プログラミング言語Go』刊行記念イベント [golang]

プログラミング言語Go

プログラミング言語Go

  • 作者: Alan A.A. Donovan
  • 出版社/メーカー: 丸善出版
  • 発売日: 2016/06/20
  • メディア: 単行本(ソフトカバー)

池袋のジュンク堂で「Goの設計思想を読み解く~実際の開発に活かすために」と題して、刊行記念イベントが開催されます。鵜飼さんとのトークイベントです。
開催日時:2016年07月06日(水) ~
場所:ジュンク堂 池袋本店
鵜飼 文敏(Googleソフトウェアエンジニア)
柴田 芳樹(『プログラミング言語Go』訳者)
19:00開場
19:30開演
事前予約が必要ですので、参加方法などの詳しい情報はこちらを見てください。

Go言語に関する日本語書籍 [golang]

これから出る本も含めてGo言語に関する日本語の書籍を列挙してみました。今年は6月までに4冊であり、Go言語の普及を後押しすると思います。

【2016年】
みんなのGo言語【現場で使える実践テクニック】

みんなのGo言語【現場で使える実践テクニック】

  • 作者: 松木雅幸
  • 出版社/メーカー: 技術評論社
  • 発売日: 2016/09/09
  • メディア: 大型本
プログラミング言語Go

プログラミング言語Go

  • 作者: Alan A.A. Donovan
  • 出版社/メーカー: 丸善出版
  • 発売日: 2016/06/20
  • メディア: 単行本(ソフトカバー)
Go言語入門

Go言語入門

  • 作者: 飛松 清
  • 出版社/メーカー: リックテレコム
  • 発売日: 2016/06/18
  • メディア: 単行本(ソフトカバー)
スターティングGo言語 (CodeZine BOOKS)

スターティングGo言語 (CodeZine BOOKS)

  • 作者: 松尾 愛賀
  • 出版社/メーカー: 翔泳社
  • 発売日: 2016/04/15
  • メディア: 単行本(ソフトカバー)
Go言語によるWebアプリケーション開発

Go言語によるWebアプリケーション開発

  • 作者: Mat Ryer
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2016/01/22
  • メディア: 大型本

【2015年】
改訂2版 基礎からわかる Go言語

改訂2版 基礎からわかる Go言語

  • 作者: 古川 昇
  • 出版社/メーカー: シーアンドアール研究所
  • 発売日: 2015/07/17
  • メディア: 単行本(ソフトカバー)

【2012年】
基礎からわかる Go言語

基礎からわかる Go言語

  • 作者: 古川 昇
  • 出版社/メーカー: シーアンドアール研究所
  • 発売日: 2012/11/21
  • メディア: 単行本(ソフトカバー)
プログラミング言語Goフレーズブック

プログラミング言語Goフレーズブック

  • 作者: David Chisnall
  • 出版社/メーカー: ピアソン桐原
  • 発売日: 2012/10/04
  • メディア: 単行本(ソフトカバー)

【2011年】
Go言語プログラミング入門on Google App Engine

Go言語プログラミング入門on Google App Engine

  • 作者: 横山 隆司
  • 出版社/メーカー: 秀和システム
  • 発売日: 2011/12/14
  • メディア: 単行本

【2010年】
はじめての「Go言語」 (I・O BOOKS)

はじめての「Go言語」 (I・O BOOKS)

  • 作者: 茨木 隆彰
  • 出版社/メーカー: 工学社
  • 発売日: 2010/11
  • メディア: 単行本


『プログラミング言語Go』翻訳作業が終了しました(3) [golang]

プログラミング言語Go

プログラミング言語Go

  • 作者: Alan A.A. Donovan
  • 出版社/メーカー: 丸善出版
  • 発売日: 2016/06/20
  • メディア: 単行本(ソフトカバー)

諸事情により、発売日が6月20日に延期されたようです。