2016-05-08 11 views
1

最初の例は失敗しますが、2番目の例はうまくいかない理由は何ですか?タイプアサーションとインターフェイス

このようなアサーションを行う正しい方法は何ですか?

例1 https://play.golang.org/p/4LRGQLdGPB

// example 1 
type Packet map[string]interface{} 

func get(pack interface{}) { 
    if packet, ok := pack.(Packet); !ok { 
     fmt.Printf("error: %#v, %#v\n", pack, packet) 
    } 
} 

func main() { 
    pack := make(map[string]interface{}) 
    pack["qwe"] = 123 
    get(pack) 
} 

// error: map[string]interface {}{"qwe":123}, main.Packet(nil) 

例2 https://play.golang.org/p/Pd9jvvNrq5

// example 2 
type Packet map[string]interface{} 

func get(pack interface{}) { 
    var p Packet 
    if packet, ok := pack.(map[string]interface{}); !ok { 
     fmt.Printf("%#v, %#v\n", pack, packet) 
    } else { 
     p = packet 
    } 
    fmt.Printf("%#v\n", p) 
} 

func main() { 
    pack := make(map[string]interface{}) 
    pack["qwe"] = 123 
    get(pack) 
} 

// main.Packet{"qwe":123} 

答えて

1

あなたは、あなたが完全に異なるタイプがあるmap[string]interface{}を渡しているPacketを渡していないという問題点ゴーが関わっている限り。

pack := make(Packet)またはpack := Packet{}を使用すると、意図したとおりに動作します。

playground

+0

も取得するには、Get(パック)を交換することによって行うことができます (パケット(パック) ) – Apin

+0

@Apin trueしかしそれは本当に無意味だろう – OneOfOne

0

回答やコメント今のところ、誤解アップミキシング、または少なくともtype assertiontype conversionの違いに多くの詳細を超えるブラッシングしています。

構文thing.(AType)はタイプアサーションです。ランタイムに評価されるとなります。これは(すなわちok == true)成功する際の基準は本当に2状況に煮詰めすることができます。

  1. thing文字通りタイプATypeのです。 Packetのような再宣言されたタイプではありません。
  2. ATypeはインターフェイスであり、thingはインターフェイスを満たしています。他のすべての場合には

okfalseになります(または、単一の値のバージョンfoo := bar.(Baz)を使用している場合、fooは、適切なゼロの値が何であれになります)。

構文AType(thing)はタイプ変換です。コンパイル時にと評価され、となります。タイプ変換では、メモリ構造がATypeで、タイプがthingであれば同一でなければなりません。

したがって、あなたの例で型アサーション、ok == falsepacket, ok := pack.(Packet)結果Packet非インタフェース型であり、packetは文字通りそのタイプではないので、それはタイプmap[string]interfaceです。タイプPacket変数packが同じ基本メモリ構造を持っているので、

しかし、あなたは、型変換Packet(pack)を行うことができ、map[string]interface{}

+0

** 1。 ATypeはインターフェイスであり、物事はインターフェイスを満たしています。**:もし 'var p interface {} = int(123)'なら 'p。(int)'と書くことができます。 、タイプAType **を保持していますか? – Exel

+0

"私はvar pのインターフェイス{} = int(123)している場合pを書くことができます。(int)なので、ルールは物事がAType型を保持するインタフェースです」は、私の1の特定のケースです。この例では、 'p'が' interface {} 'として宣言されていますが、基礎となるデータは文字通り型しかし 'type Foo int'を定義していた場合、' p'の基底のデータが 'Foo'型ではないので' p(Foo) 'が失敗することがあります。 – Endophage

+0

インタフェース2つの情報を参照します:基本となる構造体の型と構造体データ自体。 – Endophage

関連する問題