Go1のリリースノート(日本語訳)

JavaScriptを有効にしてください

前書き

Go 1 のリリースノートをChatGPTで日本語に翻訳しました。
Go 1 Release Notes

次のバージョン:Go1.1のリリースノート(日本語訳)
リリースノート一覧:Goリリース情報

Go 1の紹介

Goバージョン1、略してGo 1は、信頼性のある製品、プロジェクト、出版物を作成するための安定した基盤を提供する言語と一連のコアライブラリを定義します。

Go 1の推進動機は、ユーザーに対する安定性です。人々はGoプログラムを書き、それが数年のスケールで、Google App Engineのような本番環境を含め、変更なしにコンパイルおよび実行され続けることを期待できるべきです。同様に、人々はGoについての本を書くことができ、その本がどのバージョンのGoを説明しているかを言うことができ、そのバージョン番号が後になっても意味を持ち続けるべきです。

Go 1でコンパイルされるコードは、いくつかの例外を除いて、そのバージョンのライフタイムを通じてコンパイルおよび実行され続けるべきです。Goバージョン1.1、1.2などの更新やバグ修正を発行する際も同様です。重大な修正を除いて、Go 1の後続リリースのために言語とライブラリに加えられる変更は、機能を追加するかもしれませんが、既存のGo 1プログラムを壊すことはありません。Go 1互換性ドキュメント は、互換性ガイドラインをより詳細に説明しています。

Go 1は、今日使用されているGoの表現であり、言語の全面的な再考ではありません。新しい機能の設計を避け、問題や不整合のクリーンアップと移植性の向上に焦点を当てました。Go言語とパッケージに対するいくつかの変更は、しばらくの間検討され、プロトタイプ化されましたが、主にそれらが重要で後方互換性がないためにリリースされていませんでした。Go 1はそれらを取り出す機会であり、長期的には役立ちますが、古いプログラムに対する非互換性を導入することも意味します。幸いなことに、go fixツールは、プログラムをGo 1標準に引き上げるために必要な作業の多くを自動化できます。このドキュメントは、既存のコードを更新するプログラマーに影響を与えるGo 1の主要な変更を概説しています。その参照点は、以前のリリース、r60(タグ付けされたr60.3)です。また、r60からGo 1で実行するためのコードの更新方法も説明しています。

言語の変更

Append

appendの事前宣言された可変長引数関数は、スライスを成長させるために要素を末尾に追加するのを簡単にします。一般的な使用法は、出力を生成するときにバイトスライスの末尾にバイトを追加することです。しかし、append[]byteに文字列を追加する方法を提供していませんでした。これはもう一つの一般的なケースです。

go
1
2
greeting := []byte{}
greeting = append(greeting, []byte("hello ")...)

copyの類似の特性に類似して、Go 1は文字列をバイトスライスに直接(バイト単位で)追加することを許可し、文字列とバイトスライスの間の摩擦を減らします。変換はもはや必要ありません:

go
1
greeting = append(greeting, "world"...)

更新:
これは新しい機能なので、既存のコードに変更は必要ありません。

Close

closeの事前宣言された関数は、送信者がこれ以上値を送信しないことを示すメカニズムを提供します。これは、チャネル上のfor rangeループの実装にとって重要であり、他の状況でも役立ちます。部分的には設計によるものであり、部分的にはそうでなければ発生する可能性のある競合状態のために、これはチャネルに送信しているゴルーチンによってのみ使用されることを意図しています。データを受信しているゴルーチンではありません。しかし、Go 1以前は、closeが正しく使用されているかどうかをコンパイル時にチェックすることはありませんでした。このギャップを少なくとも部分的に埋めるために、Go 1は受信専用チャネルでのcloseを禁止します。そのようなチャネルを閉じようとすると、コンパイル時エラーになります。

go
1
2
3
4
5
6
var c chan int
var csend chan<- int = c
var crecv <-chan int = c
close(c)     // 合法
close(csend) // 合法
close(crecv) // 非合法

更新:
Go 1以前でも受信専用チャネルを閉じようとする既存のコードは誤っており、修正する必要があります。コンパイラはそのようなコードを拒否します。

複合リテラル

Go 1では、配列、スライス、またはマップ型の複合リテラルは、要素の初期化子の型指定を省略できます。これらの初期化子がポインタ型である場合です。この例の4つの初期化のすべてが合法です。最後のものはGo 1以前は違法でした。

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
type Date struct {
    month string
    day   int
}
// 構造体の値、完全修飾; 常に合法。
holiday1 := []Date{
    Date{"Feb", 14},
    Date{"Nov", 11},
    Date{"Dec", 25},
}
// 構造体の値、型名省略; 常に合法。
holiday2 := []Date{
    {"Feb", 14},
    {"Nov", 11},
    {"Dec", 25},
}
// ポインタ、完全修飾、常に合法。
holiday3 := []*Date{
    &Date{"Feb", 14},
    &Date{"Nov", 11},
    &Date{"Dec", 25},
}
// ポインタ、型名省略; Go 1で合法。
holiday4 := []*Date{
    {"Feb", 14},
    {"Nov", 11},
    {"Dec", 25},
}

更新:
この変更は既存のコードには影響しませんが、gofmt -sコマンドを既存のソースに適用すると、許可される場所で明示的な要素型を省略します。

初期化中のゴルーチン

古い言語では、初期化中に実行されるgoステートメントはゴルーチンを作成しますが、それらはプログラム全体の初期化が完了するまで実行を開始しないと定義されていました。これは多くの場所で不便を引き起こし、実質的にinit構造の有用性を制限しました:初期化中に他のパッケージがライブラリを使用する可能性がある場合、ライブラリはゴルーチンを避けることを余儀なくされました。この設計は単純さと安全性のために行われましたが、言語に対する信頼が高まるにつれて、それは不要に思えました。初期化中にゴルーチンを実行することは、通常の実行中にそれらを実行することよりも複雑でも安全でもありません。Go 1では、ゴルーチンを使用するコードは、デッドロックを導入することなく、initルーチンやグローバル初期化式から呼び出すことができます。

go
1
2
3
4
5
6
7
var PackageGlobal int

func init() {
    c := make(chan int)
    go initializationFunction(c)
    PackageGlobal = <-c
}

更新:
これは新しい機能なので、既存のコードに変更は必要ありませんが、ゴルーチンがmainの前に開始しないことに依存するコードが壊れる可能性があります。標準リポジトリにはそのようなコードはありませんでした。

rune 型

言語仕様では、int型を32ビットまたは64ビット幅にすることが許可されていますが、現在の実装では、64ビットプラットフォームでもintを32ビットに設定しています。64ビットプラットフォームでintを64ビットにすることが望ましいです。(大きなスライスをインデックスするための重要な結果があります。)しかし、この変更は、古い言語でint型がUnicodeコードポイントを保持するためにも使用されていたため、Unicode文字を処理する際にスペースを浪費します:各コードポイントは、intが32ビットから64ビットに成長した場合、余分な32ビットのストレージを浪費します。64ビットintへの変更を可能にするために、Go 1は個々のUnicodeコードポイントを表す新しい基本型、runeを導入します。それはint32のエイリアスであり、uint8のエイリアスとしてのbyteに類似しています。‘a’、‘語’、’\u0345’のような文字リテラルは、デフォルトでrune型を持ちます。これは、1.0がデフォルトでfloat64型を持つのに類似しています。文字定数に初期化された変数は、特に指定されない限り、rune型を持ちます。ライブラリは、適切な場合にintではなくruneを使用するように更新されています。たとえば、unicode.ToLowerおよび関連する関数は、runeを受け取り、返します。

go
1
2
3
4
5
6
7
delta := 'δ' // deltaはrune型を持ちます。
var DELTA rune
DELTA = unicode.ToUpper(delta)
epsilon := unicode.ToLower(DELTA + 1)
if epsilon != 'δ'+1 {
    log.Fatal("ギリシャ語の大文字小文字変換が一貫していません")
}

更新:
ほとんどのソースコードはこれによって影響を受けません。なぜなら、:=初期化子からの型推論が新しい型を静かに導入し、そこから伝播するからです。一部のコードは、簡単な変換で解決できる型エラーを受けるかもしれません。

error 型

Go 1は、新しい組み込み型、errorを導入します。これは次の定義を持ちます:

go
1
2
3
type error interface {
    Error() string
}

この型の結果はすべてパッケージライブラリにあるため、以下 で説明されています。

マップからの削除

古い言語では、マップmからキーkのエントリを削除するには、次のステートメントを書きました:

go
1
m[k] = value, false

この構文は特異な特例であり、唯一の2対1の代入でした。評価されるが破棄される値(通常は無視される)を渡す必要があり、ほぼ常に定数falseであるブール値を渡す必要がありました。それは仕事をしましたが、奇妙であり、論争の的でした。Go 1では、その構文はなくなり、代わりに新しい組み込み関数deleteがあります。呼び出し

go
1
delete(m, k)

は、式m[k]によって取得されたマップエントリを削除します。戻り値はありません。存在しないエントリを削除することは無操作です。

更新:
go fixを実行すると、プログラムから安全に破棄できる無視された値が明確であり、falseが事前定義されたブール定数を指す場合に、m[k] = value, false形式の式をdelete(m, k)に変換します。修正ツールは、プログラマーによる検査のために構文の他の使用をフラグ付けします。

マップの反復

古い言語仕様では、マップの反復順序を定義しておらず、実際にはハードウェアプラットフォームによって異なっていました。これにより、マップを反復するテストが脆弱で移植性がなく、あるマシンでは常にテストが成功し、別のマシンでは失敗するという不快な特性がありました。Go 1では、for rangeステートメントを使用してマップを反復する際に訪問される要素の順序は予測不可能であると定義されています。同じループが同じマップで複数回実行されても、コードは要素が特定の順序で訪問されることを想定してはなりません。この変更により、反復順序に依存するコードは非常に早期に壊れ、問題になる前に修正される可能性が高くなります。同様に重要なのは、プログラムがrangeループを使用してマップから要素を選択している場合でも、マップのバランスをより良くすることを保証するマップ実装を可能にすることです。

go
1
2
3
4
5
m := map[string]int{"Sunday": 0, "Monday": 1}
for name, value := range m {
    // このループは、最初にSundayが訪問されることを想定してはなりません。
    f(name, value)
}

更新:
この変更はツールでは支援できません。ほとんどの既存のコードは影響を受けませんが、一部のプログラムは壊れたり誤動作したりする可能性があります。マップ上のすべてのrangeステートメントを手動で確認し、反復順序に依存していないことを確認することをお勧めします。標準リポジトリにはそのような例がいくつかありました。それらは修正されています。反復順序に依存することはすでに不正確であり、指定されていませんでした。この変更は予測不可能性を明文化しています。

複数の代入

言語仕様は長い間、代入において右辺の式がすべて左辺の式が代入される前に評価されることを保証していました。予測可能な動作を保証するために、Go 1は仕様をさらに洗練しました。代入文の左辺に評価が必要な式(関数呼び出しや配列インデックス操作など)が含まれている場合、それらはすべて通常の左から右のルールを使用して評価され、変数が値に代入される前に評価されます。すべてが評価された後、実際の代入は左から右の順序で進行します。これらの例は動作を示しています。

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sa := []int{1, 2, 3}
i := 0
i, sa[i] = 1, 2 // i = 1, sa[0] = 2に設定されます

sb := []int{1, 2, 3}
j := 0
sb[j], j = 2, 1 // sb[0] = 2, j = 1に設定されます

sc := []int{1, 2, 3}
sc[0], sc[0] = 1, 2 // sc[0] = 1に設定され、その後sc[0] = 2に設定されます(したがって、最終的にsc[0] = 2になります)

更新:
この変更はツールでは支援できませんが、破損の可能性は低いです。標準リポジトリのコードはこの変更によって壊れませんでした。また、以前の未指定の動作に依存していたコードはすでに不正確でした。

戻り値とシャドウ変数

一般的な間違いは、結果変数と同じ名前を持つが同じ変数ではない変数への代入後に引数なしでreturnを使用することです。この状況はシャドウイングと呼ばれます:結果変数が同じ名前で宣言された別の変数によってシャドウされています。名前付き戻り値を持つ関数では、Go 1コンパイラは、戻り値のいずれかがreturnステートメントの時点でシャドウされている場合、引数なしのreturnステートメントを許可しません。(これは仕様の一部ではありません。なぜなら、これはまだ探求中の領域だからです。状況は、明示的なreturnステートメントで終了しない関数をコンパイラが拒否するのと類似しています。)この関数はシャドウされた戻り値を暗黙的に返し、コンパイラによって拒否されます:

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func Bug() (i, j, k int) {
    for i = 0; i < 5; i++ {
        for j := 0; j < 5; j++ { // jを再宣言します。
            k += i * j
            if k > 100 {
                return // 拒否されます:ここでjがシャドウされています。
            }
        }
    }
    return // OK:ここではjがシャドウされていません。
}

更新:
この方法で戻り値をシャドウするコードはコンパイラによって拒否され、手動で修正する必要があります。標準リポジトリで発生した数少ないケースはほとんどバグでした。

非公開フィールドを持つ構造体のコピー

古い言語では、異なるパッケージに属する非公開フィールドを含む構造体の値をコピーすることをパッケージに許可していませんでした。しかし、メソッドレシーバーには必要な例外がありました。また、copyappendの実装はこの制限を守っていませんでした。Go 1は、他のパッケージからの非公開フィールドを含む構造体の値をコピーすることを許可します。この変更は一貫性を解決するだけでなく、ポインタやインターフェースを使用せずに不透明な値を返す新しい種類のAPIを認めます。time.Timereflect.Valueの新しい実装は、この新しい特性を利用する型の例です。例として、パッケージpが次の定義を含む場合:

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
type Struct struct {
    Public int
    secret int
}
func NewStruct(a int) Struct {  // 注意:ポインタではありません。
    return Struct{a, f(a)}
}
func (s Struct) String() string {
    return fmt.Sprintf("{%d (secret %d)}", s.Public, s.secret)
}

pをインポートするパッケージは、p.Struct型の値を自由に代入およびコピーできます。舞台裏では、非公開フィールドは公開されているかのように代入およびコピーされますが、クライアントコードはそれらを認識することはありません。コード:

go
1
2
3
4
5
import "p"

myStruct := p.NewStruct(23)
copyOfMyStruct := myStruct
fmt.Println(myStruct, copyOfMyStruct)

は、構造体のsecretフィールドが新しい値にコピーされたことを示します。

更新:
これは新しい機能なので、既存のコードに変更は必要ありません。

等価性

Go 1以前、言語は構造体と配列の値の等価性を定義していませんでした。これは、他のことの中で、構造体と配列をマップキーとして使用できないことを意味しました。一方、Goは関数とマップの値の等価性を定義していました。関数の等価性はクロージャの存在下で問題がありました(2つのクロージャが等しいのはいつですか?)一方、マップの等価性はポインタを比較し、マップの内容を比較することは通常ユーザーが望むものではありませんでした。Go 1はこれらの問題に対処しました。まず、構造体と配列は等価性と不等価性(==!=)で比較できるようになり、したがって、要素ごとの比較を使用して、等価性が定義されている要素から構成されている場合にマップキーとして使用できます。

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
type Day struct {
    long  string
    short string
}
Christmas := Day{"Christmas", "XMas"}
Thanksgiving := Day{"Thanksgiving", "Turkey"}
holiday := map[Day]bool{
    Christmas:    true,
    Thanksgiving: true,
}
fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])

第二に、Go 1は、関数値の等価性の定義を削除しました。nilとの比較を除いてです。最後に、マップの等価性も削除されました。nilとの比較を除いてです。スライスの等価性はまだ未定義であり、計算は一般に実行不可能です。また、構造体と配列の順序付き比較演算子(< <= > >=)もまだ未定義であることに注意してください。

更新:
構造体と配列の等価性は新しい機能なので、既存のコードに変更は必要ありません。関数またはマップの等価性に依存する既存のコードはコンパイラによって拒否され、手動で修正する必要があります。影響を受けるプログラムは少ないですが、修正にはいくつかの再設計が必要かもしれません。

パッケージ階層

Go 1は、古い標準ライブラリの多くの欠陥に対処し、多くのパッケージをクリーンアップして、内部的に一貫性があり、移植性を向上させます。このセクションでは、Go 1でパッケージがどのように再配置されたかを説明します。一部は移動し、一部は名前が変更され、一部は削除されました。新しいパッケージは後のセクションで説明されています。

パッケージ階層

Go 1には、関連するアイテムをサブディレクトリにグループ化する再配置されたパッケージ階層があります。たとえば、utf8utf16は現在unicodeのサブディレクトリを占めています。また、いくつかのパッケージ は、code.google.com/p/go のサブリポジトリに移動し、他のパッケージ は完全に削除されました。

古いパス 新しいパス
asn1 encoding/asn1
csv encoding/csv
gob encoding/gob
json encoding/json
xml encoding/xml
exp/template/html html/template
big math/big
cmath math/cmplx
rand math/rand
http net/http
http/cgi net/http/cgi
http/fcgi net/http/fcgi
http/httptest net/http/httptest
http/pprof net/http/pprof
mail net/mail
rpc net/rpc
rpc/jsonrpc net/rpc/jsonrpc
smtp net/smtp
url net/url
exec os/exec
scanner text/scanner
tabwriter text/tabwriter
template text/template
template/parse text/template/parse
utf8 unicode/utf8
utf16 unicode/utf16

cmathexp/template/htmlパッケージの名前がcmplxtemplateに変更されたことに注意してください。

更新:
go fixを実行すると、標準リポジトリ内に残っているパッケージのインポートとパッケージ名の変更が更新されます。標準リポジトリにもう存在しないパッケージをインポートするプログラムは手動で編集する必要があります。

パッケージツリー exp

標準化されていないため、expディレクトリの下のパッケージは、標準のGo 1リリースディストリビューションには含まれませんが、使用したい開発者のためにリポジトリ でソースコード形式で利用可能です。Go 1のリリース時にいくつかのパッケージがexpの下に移動しました:

  • ebnf
  • html†
  • go/types

(†EscapeStringUnescapeString型はhtmlパッケージに残っています。)これらのパッケージはすべて同じ名前で利用可能で、プレフィックスexp/が付いています:exp/ebnfなど。また、utf8.String型は独自のパッケージexp/utf8stringに移動しました。最後に、gotypeコマンドは現在exp/gotypeにあり、ebnflintは現在exp/ebnflintにあります。インストールされている場合、それらは現在$GOROOT/bin/toolにあります。

更新:
expのパッケージを使用するコードは手動で更新する必要があります。または、expが利用可能なインストールからコンパイルする必要があります。go fixツールまたはコンパイラはそのような使用について警告します。

パッケージツリー old

非推奨のため、oldディレクトリの下のパッケージは、標準のGo 1リリースディストリビューションには含まれませんが、使用したい開発者のためにソースコード形式で利用可能です。新しい場所にあるパッケージは次のとおりです:

  • old/netchan

更新:
oldにあるパッケージを使用するコードは手動で更新する必要があります。または、oldが利用可能なインストールからコンパイルする必要があります。go fixツールはそのような使用について警告します。

削除されたパッケージ

Go 1はいくつかのパッケージを完全に削除します:

  • container/vector
  • exp/datafmt
  • go/typechecker
  • old/regexp
  • old/template
  • try

また、gotryコマンドも削除されました。

更新:
container/vectorを使用するコードは、直接スライスを使用するように更新する必要があります。Go言語コミュニティWiki でいくつかの提案を参照してください。他のパッケージを使用するコード(ほとんどゼロであるはずです)は再考する必要があります。

サブリポジトリに移動するパッケージ

Go 1はいくつかのパッケージを他のリポジトリ、通常はメインGoリポジトリ のサブリポジトリに移動しました。この表は古いインポートパスと新しいインポートパスを示しています:

古い 新しい
crypto/bcrypt code.google.com/p/go.crypto/bcrypt
crypto/blowfish code.google.com/p/go.crypto/blowfish
crypto/cast5 code.google.com/p/go.crypto/cast5
crypto/md4 code.google.com/p/go.crypto/md4
crypto/ocsp code.google.com/p/go.crypto/ocsp
crypto/openpgp code.google.com/p/go.crypto/openpgp
crypto/openpgp/armor code.google.com/p/go.crypto/openpgp/armor
crypto/openpgp/elgamal code.google.com/p/go.crypto/openpgp/elgamal
crypto/openpgp/errors code.google.com/p/go.crypto/openpgp/errors
crypto/openpgp/packet code.google.com/p/go.crypto/openpgp/packet
crypto/openpgp/s2k code.google.com/p/go.crypto/openpgp/s2k
crypto/ripemd160 code.google.com/p/go.crypto/ripemd160
crypto/twofish code.google.com/p/go.crypto/twofish
crypto/xtea code.google.com/p/go.crypto/xtea
exp/ssh code.google.com/p/go.crypto/ssh
image/bmp code.google.com/p/go.image/bmp
image/tiff code.google.com/p/go.image/tiff
net/dict code.google.com/p/go.net/dict
net/websocket code.google.com/p/go.net/websocket
exp/spdy code.google.com/p/go.net/spdy
encoding/git85 code.google.com/p/go.codereview/git85
patch code.google.com/p/go.codereview/patch
exp/wingui code.google.com/p/gowingui

更新:
go fixを実行すると、これらのパッケージのインポートが新しいインポートパスを使用するように更新されます。これらのパッケージに依存するインストールは、go getコマンドを使用してそれらをインストールする必要があります。

ライブラリの主要な変更

このセクションでは、最も多くのプログラムに影響を与えるコアライブラリの重要な変更について説明します。

error 型と errors パッケージ

os.Errorosパッケージに配置したのは主に歴史的な理由です:エラーは最初にosパッケージを実装する際に発生し、当時はシステム関連のように見えました。それ以来、エラーはオペレーティングシステムよりも基本的であることが明らかになりました。たとえば、syscallのようなosに依存するパッケージでエラーを使用できると良いでしょう。また、osErrorがあると、存在しないはずの多くの依存関係がosに導入されます。Go 1は、組み込みのerrorインターフェース型と、ユーティリティ関数を含む別のerrorsパッケージ(bytesstringsに類似)を導入することで、これらの問題を解決します。これはos.NewErrorerrors.New に置き換え、エラーを環境のより中心的な場所に配置します。広く使用されているStringメソッドが誤ってerrorインターフェースを満たすことを防ぐために、errorインターフェースはそのメソッドにErrorという名前を使用します:

go
1
2
3
type error interface {
    Error() string
}

fmtライブラリは、エラー値を簡単に印刷するために、すでにStringに対して行っているようにErrorを自動的に呼び出します。

go
1
2
3
4
5
6
7
8
9
type SyntaxError struct {
    File    string
    Line    int
    Message string
}

func (se *SyntaxError) Error() string {
    return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
}

すべての標準パッケージは新しいインターフェースを使用するように更新されました。古いos.Errorはなくなりました。新しいパッケージ、errors には、文字列をエラーに変換する関数func New(text string) errorが含まれています。これは古いos.NewErrorを置き換えます。

go
1
var ErrSyntax = errors.New("syntax error")

更新:
go fixを実行すると、変更の影響を受けるほとんどすべてのコードが更新されます。Stringメソッドを持つエラー型を定義するコードは、メソッドをErrorに名前を変更するために手動で更新する必要があります。

システムコールエラー

古いsyscallパッケージは、os.Error(およびほぼすべての他のもの)に先立って、エラーをint値として返していました。osパッケージは、EINVALのようなこれらのエラーの多くを転送していましたが、各プラットフォームで異なるエラーセットを使用していました。この動作は不快で移植性がありませんでした。Go 1では、syscall パッケージは、システムコールエラーに対してエラーを返します。Unixでは、実装はerrorを満たし、古いos.Errnoを置き換えるsyscall.Errno 型によって行われます。os.EINVALおよび関連する変更は他の場所 で説明されています。

更新:
go fixを実行すると、変更の影響を受けるほとんどすべてのコードが更新されます。それにもかかわらず、ほとんどのコードはsyscallではなくosパッケージを使用するべきであり、影響を受けません。

時間

時間をプログラミング言語でうまくサポートすることは常に課題です。古いGoのtimeパッケージはint64単位を持ち、実際の型安全性がなく、絶対時間と期間の区別がありませんでした。したがって、Go 1ライブラリの最も大きな変更の1つは、time パッケージの完全な再設計です。int64としてのナノ秒の整数数と、時間や年などの人間の単位を扱う別の*time.Time型の代わりに、現在は2つの基本型があります:time.Time (値なので*はなくなりました)、これは時間の瞬間を表します。そして、time.Duration 、これは間隔を表します。どちらもナノ秒の解像度を持ちます。Timeは古代の過去や遠い未来の任意の時間を表すことができ、Durationはプラスまたはマイナス約290年をカバーできます。これらの型にはメソッドがあり、time.Secondのような便利な定数期間もあります。新しいメソッドの中には、TimeDurationを追加するTime.Add や、2つのTimeを引いてDurationを得るTime.Sub があります。最も重要な意味の変化は、Unixエポック(1970年1月1日)が、Unixを言及する関数やメソッドにのみ関連するようになったことです:time.Unix と、Time型のUnix およびUnixNano メソッドです。特に、time.Now は、古いAPIではUnixエポックからのナノ秒数の整数を返していましたが、現在はtime.Time値を返します。

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// sleepUntilは指定された時間までスリープします。遅すぎる場合はすぐに戻ります。
func sleepUntil(wakeup time.Time) {
    now := time.Now() // `Time`です。
    if !wakeup.After(now) {
        return
    }
    delta := wakeup.Sub(now) // `Duration`です。
    fmt.Printf("Sleeping for %.3fs\n", delta.Seconds())
    time.Sleep(delta)
}

新しい型、メソッド、および定数は、osやファイルのタイムスタンプの表現など、時間を使用するすべての標準パッケージに伝播されています。

更新:
go fixツールは、古いtimeパッケージの多くの使用を新しい型とメソッドを使用するように更新しますが、ナノ秒/秒を表す1e9のような値は置き換えません。また、発生する値の型変更のため、修正ツールによって書き換えられた式の一部は、さらに手動で編集が必要な場合があります。そのような場合、書き換えには古い機能のための正しい関数またはメソッドが含まれますが、間違った型を持っているか、さらに分析が必要な場合があります。

ライブラリの小さな変更

このセクションでは、あまり一般的でないパッケージや、go fixを実行する必要がある以外のプログラムに影響を与える小さな変更について説明します。このカテゴリには、Go 1で新しく追加されたパッケージが含まれます。これらは、移植性を向上させ、動作を正規化し、インターフェースをよりモダンでGoらしいものにします。

archive/zip パッケージ

Go 1では、*zip.Writer にはWriteメソッドがなくなりました。その存在は間違いでした。

更新:
影響を受けるコードはほとんどなく、コンパイラによって検出され、手動で更新する必要があります。

bufio パッケージ

Go 1では、bufio.NewReaderSize およびbufio.NewWriterSize 関数は、無効なサイズに対してエラーを返さなくなりました。引数のサイズが小さすぎるか無効な場合、それは調整されます。

更新:
go fixを実行すると、エラーを_に代入する呼び出しが更新されます。修正されない呼び出しはコンパイラによって検出され、手動で更新する必要があります。

compress/flate、compress/gzip、および compress/zlib パッケージ

Go 1では、compress/flatecompress/gzip 、およびcompress/zlibNewWriterXxx関数は、圧縮レベルを取る場合は(*Writer, error)を返し、それ以外の場合は*Writerを返します。gzipパッケージのCompressorおよびDecompressor型はWriterおよびReaderに名前が変更されました。flateパッケージのWrongValueError型は削除されました。

更新:
go fixを実行すると、古い名前とエラーを_に代入する呼び出しが更新されます。修正されない呼び出しはコンパイラによって検出され、手動で更新する必要があります。

crypto/aes および crypto/des パッケージ

Go 1では、Resetメソッドが削除されました。Goはメモリがコピーされないことを保証しないため、このメソッドは誤解を招くものでした。暗号固有の型*aes.Cipher*des.Cipher、および*des.TripleDESCiphercipher.Blockに置き換えられました。

更新:
Resetの呼び出しを削除します。特定の暗号型の使用をcipher.Blockに置き換えます。

crypto/elliptic パッケージ

Go 1では、elliptic.Curve がインターフェースになり、代替実装を許可します。曲線パラメータはelliptic.CurveParams 構造体に移動しました。

更新:
*elliptic.Curveの既存のユーザーは、単にelliptic.Curveに変更する必要があります。MarshalUnmarshal、およびGenerateKeyの呼び出しは、elliptic.Curveを最初の引数として取るcrypto/ellipticの関数になりました。

crypto/hmac パッケージ

Go 1では、crypto/hmacからハッシュ固有の関数(hmac.NewMD5など)が削除されました。代わりに、hmac.Newmd5.Newのようなhash.Hashを返す関数を取ります。

更新:
go fixを実行すると、必要な変更が行われます。

crypto/x509 パッケージ

Go 1では、crypto/x509CreateCertificate 関数とCreateCRL メソッドが、以前は*rsa.PublicKeyまたは*rsa.PrivateKeyを取っていた場所にinterface{}を取るように変更されました。これにより、将来的に他の公開鍵アルゴリズムを実装できるようになります。

更新:
変更は必要ありません。

encoding/binary パッケージ

Go 1では、binary.TotalSize関数が、reflect.Valueではなくinterface{}引数を取るSize に置き換えられました。

更新:
影響を受けるコードはほとんどなく、コンパイラによって検出され、手動で更新する必要があります。

encoding/xml パッケージ

Go 1では、xml パッケージが、encoding/gob などの他のマーシャリングパッケージに近づくように設計が変更されました。古いParser型はDecoder に名前が変更され、新しいDecode メソッドを持ちます。また、Encoder 型も導入されました。Marshal およびUnmarshal 関数は、現在[]byte値で動作します。ストリームで動作するには、新しいEncoder およびDecoder 型を使用します。値をマーシャリングまたはアンマーシャリングする際、フィールドタグのサポートされるフラグの形式が、json パッケージに近づくように変更されました(xml:"name,flag")。フィールドタグ、フィールド名、およびXML属性と要素名の間の一致は、現在大文字小文字を区別します。XMLNameフィールドタグが存在する場合、それはマーシャリングされるXML要素の名前と一致する必要があります。

更新:
go fixを実行すると、パッケージのほとんどの使用が更新されますが、一部のUnmarshalの呼び出しは更新されません。フィールドタグには特別な注意が必要です。修正ツールはそれらを更新せず、手動で修正されない場合、一部のケースで静かに誤動作します。たとえば、古い"attr"は現在,attrと書かれ、プレーンな"attr"は有効ですが異なる意味を持ちます。

expvar パッケージ

Go 1では、RemoveAll関数が削除されました。*MapIter関数とIterメソッドは、Do および(*Map).Do に置き換えられました。

更新:
expvarを使用するほとんどのコードは変更を必要としません。Iterを使用していたまれなコードは、クロージャをDoに渡して同じ効果を達成するように更新できます。

flag パッケージ

Go 1では、インターフェースflag.Value がわずかに変更されました。Setメソッドは、成功または失敗を示すためにboolではなくエラーを返すようになりました。また、新しい種類のフラグDurationがあり、時間間隔を指定する引数値をサポートします。そのようなフラグの値は、time.Durationがそれらをフォーマットするのと同様に、単位を指定する必要があります:10s1h30mなど。

go
1
var timeout = flag.Duration("timeout", 30*time.Second, "完了を待つ時間")

更新:
独自のフラグを実装するプログラムは、Setメソッドを更新するために手動で小さな修正が必要です。Durationフラグは新しく、既存のコードには影響しません。

go/* パッケージ

goの下のいくつかのパッケージは、わずかに改訂されたAPIを持っています。パッケージgo/scannergo/parsergo/printer 、およびgo/doc で、構成モードフラグのための具体的なMode型が導入されました。go/scanner パッケージからAllowIllegalCharsInsertSemisモードが削除されました。これらは主にGoソースファイル以外のテキストをスキャンするために役立ちました。その目的のために、text/scanner パッケージを使用する必要があります。スキャナのInit メソッドに提供されるErrorHandler は、現在単に関数であり、インターフェースではありません。ErrorVector型は、既存のErrorList 型に置き換えられ、ErrorVectorメソッドが移行されました。スキャナのクライアントにErrorVectorを埋め込む代わりに、クライアントはErrorListを維持する必要があります。go/parser パッケージによって提供される解析関数のセットは、主要な解析関数ParseFile と、いくつかの便利な関数ParseDir およびParseExpr に減少しました。go/printer パッケージは、追加の構成モードSourcePos をサポートしています。設定されている場合、プリンタは//lineコメントを出力し、生成された出力に元のソースコードの位置情報を含めます。新しい型CommentedNode は、任意のast.Node に関連付けられたコメントを提供するために使用できます(これまでast.Fileのみがコメント情報を持っていました)。go/doc パッケージの型名は、Docサフィックスを削除して簡素化されました:PackageDocPackageになり、ValueDocValueになりました。また、すべての型は一貫してNameフィールド(またはValue型の場合はNames)を持ち、Type.FactoriesType.Funcsになりました。doc.NewPackageDoc(pkg, importpath)を呼び出す代わりに、パッケージのドキュメントは次のように作成されます:

go
1
doc.New(pkg, importpath, mode)

新しいmodeパラメータは操作モードを指定します:AllDecls が設定されている場合、すべての宣言(エクスポートされたものだけでなく)が考慮されます。NewFileDoc関数は削除され、CommentText関数はast.CommentGroup のメソッドText になりました。go/token パッケージでは、token.FileSet メソッドFiles(元々は*token.Filesのチャネルを返していました)は、関数引数を受け入れるイテレータIterate に置き換えられました。go/build パッケージでは、APIがほぼ完全に置き換えられました。パッケージはまだGoパッケージ情報を計算しますが、ビルドを実行しません:CmdScript型はなくなりました。(コードをビルドするには、新しいgo コマンドを使用してください。)DirInfo型は現在Package と呼ばれています。FindTreeScanDirは、ImportImportDir に置き換えられました。

更新:
goのパッケージを使用するコードは手動で更新する必要があります。コンパイラは不正な使用を拒否します。go/doc型と一緒に使用されるテンプレートは手動で修正が必要な場合があります。名前が変更されたフィールドは実行時エラーを引き起こします。

hash パッケージ

Go 1では、hash.Hash の定義に新しいメソッドBlockSizeが含まれています。この新しいメソッドは主に暗号ライブラリで使用されます。hash.Hash インターフェースのSumメソッドは、ハッシュ値が追加される[]byte引数を取るようになりました。以前の動作は、呼び出しにnil引数を追加することで再現できます。

更新:
hash.Hashの既存の実装は、BlockSizeメソッドを追加する必要があります。入力を1バイトずつ処理するハッシュは、BlockSizeを実装して1を返すことができます。go fixを実行すると、hash.Hashのさまざまな実装のSumメソッドの呼び出しが更新されます。

更新:
パッケージの機能が新しいため、更新は必要ありません。

http パッケージ

Go 1では、http パッケージがリファクタリングされ、一部のユーティリティがhttputil サブディレクトリに移動されました。これらの部分はHTTPクライアントによってほとんど必要とされません。影響を受ける項目は次のとおりです:

  • ClientConn
  • DumpRequest
  • DumpRequestOut
  • DumpResponse
  • NewChunkedReader
  • NewChunkedWriter
  • NewClientConn
  • NewProxyClientConn
  • NewServerConn
  • NewSingleHostReverseProxy
  • ReverseProxy
  • ServerConn

Request.RawURLフィールドは削除されました。それは歴史的な遺物でした。HandleおよびHandleFunc関数、およびServeMuxの同様に名前付けられたメソッドは、同じパターンを2回登録しようとするとパニックを起こします。

更新:
go fixを実行すると、影響を受けるプログラムが更新されますが、RawURLの使用は手動で修正する必要があります。

image パッケージ

image パッケージには、いくつかの小さな変更、再配置、および名前の変更があります。色処理コードのほとんどは独自のパッケージimage/color に移動しました。移動した要素については、対称性が生じます。たとえば、image.RGBA の各ピクセルはcolor.RGBA です。古いimage/ycbcrパッケージは、いくつかの名前の変更を伴い、image およびimage/color パッケージに統合されました。古いimage.ColorImage型はまだimageパッケージにありますが、image.Uniformに名前が変更されました。一方、image.Tiledは削除されました。この表は名前の変更を示しています。

古い 新しい
image.Color color.Color
image.ColorModel color.Model
image.ColorModelFunc color.ModelFunc
image.PalettedColorModel color.Palette
image.RGBAColor color.RGBA
image.RGBA64Color color.RGBA64
image.NRGBAColor color.NRGBA
image.NRGBA64Color color.NRGBA64
image.AlphaColor color.Alpha
image.Alpha16Color color.Alpha16
image.GrayColor color.Gray
image.Gray16Color color.Gray16
image.RGBAColorModel color.RGBAModel
image.RGBA64ColorModel color.RGBA64Model
image.NRGBAColorModel color.NRGBAModel
image.NRGBA64ColorModel color.NRGBA64Model
image.AlphaColorModel color.AlphaModel
image.Alpha16ColorModel color.Alpha16Model
image.GrayColorModel color.GrayModel
image.Gray16ColorModel color.Gray16Model
ycbcr.RGBToYCbCr color.RGBToYCbCr
ycbcr.YCbCrToRGB color.YCbCrToRGB
ycbcr.YCbCrColorModel color.YCbCrModel
ycbcr.YCbCrColor color.YCbCr
ycbcr.YCbCr image.YCbCr
ycbcr.SubsampleRatio444 image.YCbCrSubsampleRatio444
ycbcr.SubsampleRatio422 image.YCbCrSubsampleRatio422
ycbcr.SubsampleRatio420 image.YCbCrSubsampleRatio420
image.ColorImage image.Uniform

imageパッケージのNew関数(NewRGBANewRGBA64 など)は、4つの整数の代わりにimage.Rectangle を引数として取ります。最後に、新しい定義済みのcolor.Color変数color.Blackcolor.Whitecolor.Opaque 、およびcolor.Transparent があります。

更新:
go fixを実行すると、変更の影響を受けるほとんどすべてのコードが更新されます。

log/syslog パッケージ

Go 1では、syslog.NewLogger 関数がエラーとlog.Loggerを返します。

更新:
影響を受けるコードはほとんどなく、コンパイラによって検出され、手動で更新する必要があります。

mime パッケージ

Go 1では、mimeパッケージのFormatMediaType 関数が、ParseMediaType と一貫性を持たせるために簡素化されました。現在は"text/html"を取ります。以前は"text""html"を取っていました。

更新:
影響を受けるコードはほとんどなく、コンパイラによって検出され、手動で更新する必要があります。

net パッケージ

Go 1では、さまざまなSetTimeoutSetReadTimeout、およびSetWriteTimeoutメソッドが、それぞれSetDeadlineSetReadDeadline 、およびSetWriteDeadline に置き換えられました。接続上の任意のアクティビティに適用されるナノ秒単位のタイムアウト値を取る代わりに、新しいメソッドは、読み取りと書き込みがタイムアウトし、ブロックしなくなる絶対期限(time.Time値として)を設定します。また、新しい関数net.DialTimeout があり、ネットワークアドレスのダイヤルをタイムアウトするのを簡素化し、複数のリスナーで同時にマルチキャストUDPをリッスンできるようにするnet.ListenMulticastUDP があります。net.ListenMulticastUDP関数は、古いJoinGroupおよびLeaveGroupメソッドを置き換えます。

更新:
古いメソッドを使用するコードはコンパイルに失敗し、手動で更新する必要があります。意味の変更により、修正ツールが自動的に更新するのは困難です。

os パッケージ

Time関数は削除されました。呼び出し元はtimeパッケージのTime 型を使用する必要があります。Exec関数は削除されました。呼び出し元は、利用可能な場合はsyscallパッケージのExecを使用する必要があります。ShellExpand関数はExpandEnv に名前が変更されました。NewFile 関数は、intの代わりにuintptr fdを取るようになりました。ファイルのFd メソッドもuintptrを返します。osパッケージには、基盤となるオペレーティングシステムに応じて値が異なるため、EINVALのようなエラー定数はもうありません。一般的なエラーのプロパティをテストするための新しいポータブル関数IsPermission などがあり、よりGoらしい名前の新しいエラー値ErrPermissionErrNotExist があります。Getenverror関数は削除されました。存在しない環境変数と空の文字列を区別するには、os.Environ またはsyscall.Getenv を使用します。Process.Wait メソッドはオプション引数を削除し、関連する定数はパッケージから削除されました。また、Wait関数はなくなり、Process型のメソッドのみが残っています。Process.Wait によって返されるWaitmsg型は、よりポータブルなProcessState 型に置き換えられ、プロセスに関する情報を取得するためのアクセサメソッドがあります。Waitの変更により、ProcessState値は常に終了したプロセスを記述します。移植性の懸念により、インターフェースが他の方法で簡素化されましたが、ProcessState.Sys およびProcessState.SysUsage メソッドによって返される値は、Unix上のsyscall.WaitStatussyscall.Rusage などの基盤となるシステム固有のデータ構造に型アサーションできます。

更新:
go fixを実行すると、Process.Waitへのゼロ引数が削除されます。他のすべての変更はコンパイラによって検出され、手動で更新する必要があります。

os.FileInfo 型

Go 1は、os.FileInfo 型を再定義し、構造体からインターフェースに変更しました:

go
1
2
3
4
5
6
7
8
type FileInfo interface {
    Name() string       // ファイルのベース名
    Size() int64        // バイト単位の長さ
    Mode() FileMode     // ファイルモードビット
    ModTime() time.Time // 変更時間
    IsDir() bool        // Mode().IsDir()の略
    Sys() interface{}   // 基盤となるデータソース(nilを返すことができます)
}

ファイルモード情報は、os.FileModeと呼ばれるサブタイプに移動しました。これは、IsDirPerm、およびStringメソッドを持つ単純な整数型です。ファイルモードやプロパティ(Unix上のi-numberなど)のシステム固有の詳細は、FileInfoから完全に削除されました。代わりに、各オペレーティングシステムのosパッケージは、FileInfoインターフェースの実装を提供し、Sysメソッドがファイルメタデータのシステム固有の表現を返します。たとえば、Unixシステム上のファイルのi-numberを発見するには、次のようにFileInfoをアンパックします:

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
fi, err := os.Stat("hello.go")
if err != nil {
    log.Fatal(err)
}
// それがUnixファイルであることを確認します。
unixStat, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
    log.Fatal("hello.go: Unixファイルではありません")
}
fmt.Printf("ファイルi-number: %d\n", unixStat.Ino)

(賢明ではありませんが)“hello.go"がUnixファイルであると仮定すると、i-number式は次のように短縮できます:

go
1
fi.Sys().(*syscall.Stat_t).Ino

FileInfoの使用の大部分は、標準インターフェースのメソッドのみを必要とします。osパッケージには、ENOENTのようなPOSIXエラーのラッパーはもう含まれていません。特定のエラー条件を検証する必要があるプログラムは、現在、ブール関数IsExistIsNotExist 、およびIsPermission を使用できます。

go
1
2
3
4
f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if os.IsExist(err) {
    log.Printf("%sはすでに存在します", name)
}

更新:
go fixを実行すると、現在のos.FileInfoおよびos.FileModeAPIの古い同等のものを使用するコードが更新されます。システム固有のファイルの詳細が必要なコードは手動で更新する必要があります。osパッケージの古いPOSIXエラー値を使用するコードはコンパイルに失敗し、手動で更新する必要もあります。

os/signal パッケージ

Go 1のos/signalパッケージは、すべての受信信号を受信するチャネルを返すIncoming関数を、既存のチャネルで特定の信号の配信を要求する選択的なNotify関数に置き換えました。

更新:
コードは手動で更新する必要があります。c := signal.Incoming()の文字通りの翻訳は次のとおりです:

go
1
2
c := make(chan os.Signal, 1)
signal.Notify(c) // すべての信号を要求します

しかし、ほとんどのコードは処理したい特定の信号をリストする必要があります:

go
1
2
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)

path/filepath パッケージ

Go 1では、path/filepathパッケージのWalk 関数が、Visitorインターフェース値の代わりにWalkFunc 型の関数値を取るように変更されました。WalkFuncは、ファイルとディレクトリの両方の処理を統一します。

go
1
type WalkFunc func(path string, info os.FileInfo, err error) error

WalkFunc関数は、開けなかったファイルやディレクトリに対しても呼び出されます。その場合、error引数が失敗を説明します。ディレクトリの内容をスキップする場合、関数は値filepath.SkipDir を返すべきです。

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
markFn := func(path string, info os.FileInfo, err error) error {
    if path == "pictures" { // ディレクトリ「pictures」とその内容のウォークをスキップします。
        return filepath.SkipDir
    }
    if err != nil {
        return err
    }
    log.Println(path)
    return nil
}
err := filepath.Walk(".", markFn)
if err != nil {
    log.Fatal(err)
}

更新:
この変更はほとんどのコードを簡素化しますが、微妙な影響があるため、影響を受けるプログラムは手動で更新する必要があります。コンパイラは古いインターフェースを使用しているコードを検出します。

regexp パッケージ

regexp パッケージは書き直されました。インターフェースは同じですが、サポートする正規表現の仕様が古い「egrep」形式からRE2 の形式に変更されました。

更新:
このパッケージを使用するコードは、正規表現を手動で確認する必要があります。

runtime パッケージ

Go 1では、runtimeパッケージによってエクスポートされるAPIの多くが、他のパッケージによって提供される機能に置き換えられました。runtime.Typeインターフェースまたはその具体的な型実装を使用するコードは、今後はreflect パッケージを使用する必要があります。runtime.Semacquireruntime.Semreleaseを使用するコードは、チャネルやsync パッケージの抽象化を使用するべきです。runtime.Allocruntime.Free、およびruntime.Lookup関数は、メモリアロケータをデバッグするために作成された安全でないAPIであり、置き換えはありません。以前は、runtime.MemStatsはメモリアロケーションに関する統計を保持するグローバル変数であり、runtime.UpdateMemStatsの呼び出しによって最新の状態が保証されていました。Go 1では、runtime.MemStatsは構造体型であり、現在の統計を取得するためにruntime.ReadMemStats を使用する必要があります。このパッケージには、新しい関数runtime.NumCPU が追加され、オペレーティングシステムのカーネルによって報告される並列実行に利用可能なCPUの数を返します。その値はGOMAXPROCSの設定に役立ちます。runtime.Cgocallsruntime.Goroutines関数は、それぞれruntime.NumCgoCallruntime.NumGoroutineに名前が変更されました。

更新:
go fixを実行すると、関数の名前変更に対応するコードが更新されます。他のコードは手動で更新する必要があります。

strconv パッケージ

Go 1では、strconv パッケージが大幅に再設計され、よりGoらしく、Cらしさが減りましたが、Atoiは存続しています(これはint(ParseInt(x, 10, 0))に似ています)。また、Itoa(x)FormatInt(int64(x), 10))も存続しています。バイトスライスに追加する新しいバリアントもあり、アロケーションの制御を可能にします。この表は名前変更をまとめたものです。詳細はパッケージドキュメント を参照してください。

旧呼び出し 新呼び出し
Atob(x) ParseBool(x)
Atof32(x) ParseFloat(x, 32)§
Atof64(x) ParseFloat(x, 64)
AtofN(x, n) ParseFloat(x, n)
Atoi(x) Atoi(x)
Atoi(x) ParseInt(x, 10, 0)§
Atoi64(x) ParseInt(x, 10, 64)
Atoui(x) ParseUint(x, 10, 0)§
Atoui64(x) ParseUint(x, 10, 64)
Btoi64(x, b) ParseInt(x, b, 64)
Btoui64(x, b) ParseUint(x, b, 64)
Btoa(x) FormatBool(x)
Ftoa32(x, f, p) FormatFloat(float64(x), f, p, 32)
Ftoa64(x, f, p) FormatFloat(x, f, p, 64)
FtoaN(x, f, p, n) FormatFloat(x, f, p, n)
Itoa(x) Itoa(x)
Itoa(x) FormatInt(int64(x), 10)
Itoa64(x) FormatInt(x, 10)
Itob(x, b) FormatInt(int64(x), b)
Itob64(x, b) FormatInt(x, b)
Uitoa(x) FormatUint(uint64(x), 10)
Uitoa64(x) FormatUint(x, 10)
Uitob(x, b) FormatUint(uint64(x), b)
Uitob64(x, b) FormatUint(x, b)

更新:
go fixを実行すると、変更の影響を受けたほとんどのコードが更新されます。

§ Atoiは存続していますが、AtouiAtof32は存続していないため、キャストが必要になる場合があります。go fixツールはそれについて警告します。

template パッケージ

templateおよびexp/template/htmlパッケージは、text/template およびhtml/template に移動しました。より重要なのは、これらのパッケージのインターフェースが簡素化されたことです。テンプレート言語は同じですが、「テンプレートセット」の概念がなくなり、パッケージの関数とメソッドがそれに応じて変更され、多くの場合削除されました。セットの代わりに、Templateオブジェクトは複数の名前付きテンプレート定義を含むことができ、テンプレート呼び出しのための名前空間を実質的に構築します。テンプレートは、それに関連付けられた他のテンプレートを呼び出すことができますが、それに関連付けられたテンプレートのみを呼び出すことができます。テンプレートを関連付ける最も簡単な方法は、それらを一緒に解析することであり、新しいパッケージ構造によりこれが容易になりました。

更新:
インポートはfixツールによって更新されます。単一テンプレートの使用はほとんど影響を受けません。複数のテンプレートを連携して使用するコードは手動で更新する必要があります。text/templateのドキュメント にある例が参考になります。

testing パッケージ

testingパッケージには、ベンチマーク関数に引数として渡されるB型があります。Go 1では、Bに新しいメソッドが追加され、Tのメソッドに類似しており、ログ記録と失敗報告を可能にします。

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
func BenchmarkSprintf(b *testing.B) {
    // ベンチマークを実行する前に正確性を確認します。
    b.StopTimer()
    got := fmt.Sprintf("%x", 23)
    const expect = "17"
    if expect != got {
        b.Fatalf("expected %q; got %q", expect, got)
    }
    b.StartTimer()
    for i := 0; i < b.N; i++ {
        fmt.Sprintf("%x", 23)
    }
}

更新:
既存のコードは影響を受けませんが、printlnpanicを使用するベンチマークは新しいメソッドを使用するように更新する必要があります。

testing/script パッケージ

testing/scriptパッケージは削除されました。それは残骸でした。

更新:
コードが影響を受ける可能性は低いです。

unsafe パッケージ

Go 1では、unsafe.Typeofunsafe.Reflectunsafe.Unreflectunsafe.New、およびunsafe.NewArray関数が削除されました。これらは、reflect パッケージによって提供されるより安全な機能を重複していました。

更新:
これらの関数を使用するコードは、reflect パッケージを使用するように書き直す必要があります。encoding/gob およびプロトコルバッファライブラリ への変更が例として役立つかもしれません。

url パッケージ

Go 1では、url.URL 型のいくつかのフィールドが削除または置き換えられました。String メソッドは、URLのすべてのフィールドを必要に応じて使用して、エンコードされたURL文字列を予測可能に再構築します。結果の文字列には、パスワードがエスケープされなくなります。Rawフィールドは削除されました。ほとんどの場合、Stringメソッドを代わりに使用できます。古いRawUserinfoフィールドは、*net.Userinfo 型のUserフィールドに置き換えられました。この型の値は、新しいnet.User およびnet.UserPassword 関数を使用して作成できます。EscapeUserinfoおよびUnescapeUserinfo関数も削除されました。RawAuthorityフィールドは削除されました。同じ情報はHostおよびUserフィールドにあります。RawPathフィールドとEncodedPathメソッドは削除されました。ルート付きURL(スキーマの後にスラッシュがあるもの)のパス情報は、デコードされた形式でのみPathフィールドにあります。時折、デコードプロセスで失われた情報を取得するためにエンコードされたデータが必要になる場合があります。これらのケースは、URLが構築されたデータにアクセスすることで処理する必要があります。ルートなしのパスを持つURL(例: “mailto:dev@golang.org?subject=Hi”)も異なる方法で処理されます。OpaquePathブールフィールドは削除され、エンコードされたパスを保持するために新しいOpaque文字列フィールドが導入されました。Go 1では、引用されたURLは次のように解析されます:

go
1
2
3
4
5
URL{
    Scheme: "mailto",
    Opaque: "dev@golang.org",
    RawQuery: "subject=Hi",
}

新しいRequestURI メソッドがURLに追加されました。ParseWithReference関数はParseWithFragmentに名前が変更されました。

更新:
古いフィールドを使用するコードはコンパイルに失敗し、手動で更新する必要があります。意味的な変更により、fixツールが自動的に更新することは困難です。

go コマンド

Go 1は、Goパッケージとコマンドを取得、ビルド、インストールするためのツールであるgoコマンド を導入しました。goコマンドは、Makefileを廃止し、Goのソースコードを使用して依存関係を見つけ、ビルド条件を決定します。ほとんどの既存のGoプログラムは、ビルドにMakefileを必要としなくなります。goコマンドの入門書としてHow to Write Go Code を参照し、詳細はgoコマンドのドキュメント を参照してください。

更新:
Goプロジェクトの古いMakefileベースのビルドインフラストラクチャ(Make.pkg、Make.cmdなど)に依存するプロジェクトは、Goコードのビルドにgoコマンドを使用するように切り替え、必要に応じてMakefileを再作成して補助的なビルドタスクを実行する必要があります。

cgo コマンド

Go 1では、cgoコマンド は異なる_cgo_export.hファイルを使用します。これは、//export行を含むパッケージに対して生成されます。_cgo_export.hファイルは、エクスポートされた関数定義がそこで定義された型を使用できるように、Cのプレアンブルコメントで始まります。これにより、プレアンブルが複数回コンパイルされるため、//exportを使用するパッケージは、Cのプレアンブルに関数定義や変数の初期化を置いてはいけません。

パッケージリリース

Go 1に関連する最も重要な変更の1つは、事前にパッケージ化されたダウンロード可能なディストリビューションの利用可能性です。これらは、アーキテクチャとオペレーティングシステムの多くの組み合わせ(Windowsを含む)で利用可能であり、リストは増え続けます。インストールの詳細はGetting Started ページに記載されており、ディストリビューション自体はダウンロードページ にリストされています。


スポンサーリンク

共有

もふもふ
著者
もふもふ
プログラマ。汎用系→ゲームエンジニア→Webエンジニア→QAエンジニア