Nil スライスと「nil」の比較が Go の具象型とインターフェイスで異なるのはなぜですか?

Barbara Streisand
リリース: 2024-11-03 08:45:03
オリジナル
310 人が閲覧しました

Why Does Comparing a Nil Slice to `nil` Differ Between Concrete Types and Interfaces in Go?

インターフェースの型と nil スライス

Go では、インターフェースの型を期待する関数に変数を渡すとき、動作は以下に基づいて異なる場合があります。変数がスライスであるかどうかを判断します。

次のスニペットを考えてみましょう:

<code class="go">package main

import "fmt"

func main() {
    var i []int = nil
    yes(i) // output: true
    no(i)  // output: false
}

func yes(thing []int) {
    fmt.Println(thing == nil)
}

func no(thing interface{}) {
    fmt.Println(thing == nil)
}</code>
ログイン後にコピー

このプログラムでは、yes 関数は整数のスライスを期待し、no 関数はインターフェイスを期待します。タイプ。 nil スライス i を指定して yes を呼び出すと、スライス自体が nil であるため、出力は true になります。ただし、nil スライスを指定して no を呼び出すと false になります。

なぜこれが起こるのかを理解するには、Go のインターフェイスの実装を詳しく調べる必要があります。内部的には、インターフェイス型は 2 つのフィールドを含む構造体として表されます。Itab は型記述子を参照し、Data は実際の値を保持します。

nil スライスを yes に渡すと、nil 値のみが返されます。が Data として渡されると、比較は事実上 nil == nil となり、これは true になります。ただし、nil スライスを no に渡すと、Go は自動的にそれをインターフェイス型にラップし、no(interface{[]int, nil}) のような結果になります。この場合、比較は、interface{[]int, nil} == nil となり、基礎となるデータが nil であっても、インターフェイスの型自体が nil ではないため、false を返します。

この動作は原因である可能性があります。インターフェイスの性質と、インターフェイスが nil 値とどのように相互作用するかについて説明します。 Go FAQ で説明されているように、nil インターフェースと nil 具象値は別個の概念です。インターフェイスタイプが nil 値を保持している場合、それはインターフェイス自体が nil であることを意味しません。したがって、nil 値を含むインターフェース型を nil と比較すると、結果は false になります。

以上がNil スライスと「nil」の比較が Go の具象型とインターフェイスで異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート