1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Goのインターフェース型がnilになるのは(nil型, 0x0)という(型, 値)ペアのときだけ

Last updated at Posted at 2019-08-18

まとめ

  • 内部的にGoのインターフェースは(型, 値)という2つのペアを持つ。
  • インターフェース型がnilになるのは(nil型, 0x0)という(型, 値)ペアのときだけ。

GoのFAQにて言及されています。

nilとerror型のnilとがイコールにならないのは?
内部的にインタフェースは「型」と「値」の2要素から成ります。この「値」は実際の任意な値であり、インタフェースの「動的な値」と呼ばれます。「型」はその値の型です。仮に、あるインタフェース値がint型の3であるとき(int, 3)と表すとします。
インタフェースの値がnilとなるのは、内部の値と型がともにセットされていないとき(nil, nil)だけです。詳しく述べれば、nilインタフェースは常にnil型を保持しています。ポインタ型であるintをインタフェース内に格納したとき、ポインタの値に関わらず内部の型はint(*int, ?)になります。ポインタの値がnilであっても、このインタフェース値はnilにはなりません。

検証コード

package main

func main() {
	var x *int32 = nil
	var y *int64 = nil

	// xとnilの比較は値同士なので一致
	println(x == nil) // true

	// xとyはそれぞれ(*int32, nil), (*int64, nil)
	// のペアのインターフェース型へキャストされる。
	xx := interface{}(x)
	yy := interface{}(y)
	println(interface{}(x)) // (0x94b60,0x0)
	println(interface{}(y)) // (0x94ba0,0x0)
	// ペアの中身が違うのでxxとyyの比較は不一致
	println(xx == yy) // false
	// xx,yyは(nil, nil)ペアではないのでnilとの比較は不一致
	println(xx == nil) // false

	// 【ちなみに】 nilはnil値を持てる型へキャストできる
	// nilはnil値の型*int32へキャスト可
	println((*int32)(nil)) // 0x0 (<- nil)
	// 型int32はnil値を持てないのでキャスト不可
	// e := (int32)(nil) // コンパイルエラー
}
出力
true
(0x94b60,0x0)
(0x94ba0,0x0)
false
false
0x0

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?