web-dev-qa-db-ja.com

Goがnilと入力したのはなぜですか?

Goにtypednilがあるのはなぜですか?便宜上、明示的なインターフェース適合性チェックをスローします。型なしnilの問題は何ですか?デザイナーは型付きnilで何を解決したいですか?

28
Eonil

このエラーメッセージについて質問しているようです:

http://play.golang.org/p/h80rmDYCTI

_package main

import "fmt"

type A struct {}
type B struct {}

func (a *A) Foo() {
    fmt.Println("A")
}

func (b *B) Foo() {
    fmt.Println("B")
}

func main() {
    n := nil
    n.Foo()
}
_

これは印刷します:

_prog.go:17: use of untyped nil
 [process exited with non-zero status]
_

その例では、プログラムは「A」または「B」を印刷する必要がありますか?

コンパイラの決定を支援する必要があります。その方法は、nのタイプを指定することです。

例えば:

http://play.golang.org/p/zMxUFYgxpy

_func main() {
    var n *A
    n.Foo()
}
_

「A」を出力します。

他の言語では、nnilまたは同等のものである場合、n.Foo()はすぐにクラッシュする可能性があります。 Goの言語デザイナーは、代わりに何をすべきかをユーザーに判断させることにしました。 nilをチェックせずにポインターにアクセスすると、他の言語と同じ動作になります。

14
Sean

これはタイプセーフのためです。 nilは、実際にはGoのuninitialized変数の値です。スライス、マップ、関数、チャネル、ポインター、およびインターフェースのnil値は、同じタイプではなく、比較できません。詳細は 言語仕様 を参照してください。

編集: @ newacct で指摘されているように、これの正しい専門用語は、タイプの "zero value" です。

宣言またはmakeまたはnewの呼び出しによって値を格納するためにメモリが割り当てられ、明示的な初期化が提供されない場合、メモリにはデフォルトの初期化が与えられます。そのような値の各要素は、その型のゼロ値に設定されます。ブール値の場合はfalse、整数の場合は0、浮動小数点数の場合は0.0、文字列の場合は ""、ポインター、関数、インターフェイス、スライス、チャネル、およびマップの場合はnilです。

遊び場の例

Go FAQ にnilのインターフェイスとエラーに関する情報もあります なぜnilのエラー値がnilと等しくないのですか?

13
Intermernet

Golangのすべての変数には型が必要です。 :=演算子を使用すると、右側の式の型から型が推測されます。

x := [0]int{}       // var x [0]int
y := make(chan int) // var y chan int
z := map[int]int{}  // var z map[int]int
a := func(int) {}   // var a func(int)
b := 42             // var b int
c := 42.0           // var c float64

ほとんどすべての式について、どこかに明示的にタイプを指定する必要があるため、または数値リテラルの場合は、指定されていないときにデフォルトが使用されるため、そのタイプは明確です。このルールの唯一の例外はnilです。

n := nil // var n ???

nilは、以下の有効な値です。

  • ポインタ
  • 安全でないポインタ
  • インターフェース
  • チャンネル
  • Maps
  • スライス
  • 機能

ユーザーがnilを入力したときのタイプには適切なデフォルトがないため、代わりにGolangはこれを拒否し、明示的なタイプ指定を要求します。

2
Konrad Borowski

Typed-nilがないと、nil値で短い割り当てステートメント:=を使用できません。

a := nil // Error: use of untyped nil
b := error(nil) // OK

同様に、次のワンライナーを有効にします。

result, err := "A good result", error(nil)

上記のようなものを書くと、時々便利になるかもしれません。


ただし、nilはキーワードまたはリテラルではなく、Goには組み込みがないが組み込みまたは標準typed-nil値。 Typed-nilは、次のいずれかの結果としてのみ存在します。

  • デフォルト(「ゼロ値」)の初期化でnillable型付き変数を宣言する
  • nilを(直接的または間接的に)型付き値に割り当てる
  • nil識別子を型にキャストする(上記の例に示すように)。

ここに、タイプされたnilとインターフェイスの微妙さに関するクリップがあります。 GopherCon 2015:Kevin Cantwell-何が問題なのでしょうか?

0
nobar