2013-05-30 9 views
9

私はこのようなのfloat64にint型に変換することができますタイプはいずれかのインターフェイスが保持している具体的なタイプでなければなりません」、または:アサーションを入力に関して移動型アサーション変換

var a int = 10 
var b float64 = float64(a) 

、効果的な移動は述べてその値を。に変換できる第2のインタフェース型。 '念頭に置いて

、なぜ次は失敗しない:

func foo(a interface{}) { 
    fmt.Println(a.(float64)) 
} 

func main() { 
    var a int = 10 
    foo(a) 
} 

これはpanic: interface conversion: interface is int, not float64が発生します。

「インターフェイスタイプおよびタイプTのX発現のために、一次式

x.(T) 

xはゼロではなく、値がに格納されていることと主張:GO仕様が言うこと

注xはT型です。 '

Effective Go文と矛盾しますが、私が見ているものと一線を画しているようです。

答えて

9

This sentence実際には、実際には混乱しているようです。その時、作者がstructsについて考えていたようです。

The chapter on assertions in the specificationはより明確である:インターフェイスタイプおよびタイプTのX発現のため

、プライマリ 発現

X(T)は、xがゼロでない値ことと主張しています。 xに格納されている値は、 タイプTです。x(T)という表記は、タイプアサーションと呼ばれます。

より正確には、Tがインタフェースタイプでない場合、x。(T)は、xの動的タイプがタイプTと同一であることを主張します。この場合、Tは はx ;それ以外の場合は、xがタイプTの値を格納することができないため、タイプアサーションは で無効です。 Tがインターフェイスタイプである場合、x。(T)はx の動的タイプがインターフェイスTを実装すると主張します。

事実you can convert your int to a float(とその逆)は、それらが同じタイプであると主張することはできません。

+0

のタイプ変換を使用しますが、ランタイムパニックメッセージで示唆されているように、操作は実際にはアサーションではなく「インターフェイス変換」です。このような変換が自然に起こるといいですね。 – Ferguzz

+0

タイプスイッチを行うことができます。あなたはもっと自然なことを思いついていますか? –

+0

@Ferguzz:Goはすべてのコンバージョンで明示的です。暗黙的または自動的なコンバージョンはありません。これはとても良いことです。 「自然な変換」の種類は明示的なものとは完全に逆です。 – Volker

8

タイプはいずれかのインターフェイスに保持されている具体的なタイプ、または値が

に変換することができる第二インタフェースタイプでこれは基本的に説明しなければならないfollowing

package main 

import "fmt" 

type Stringer interface { 
    String() 
} 

type Byter interface { 
    Bytes() 
} 

type Stringbyter interface { 
    Stringer 
    Byter 
} 

type Polymorphic float64 

func (p *Polymorphic) String() {} 

func (p *Polymorphic) Bytes() {} 

func main() { 
    i := interface{}(new(Polymorphic)) 
    if _, ok := i.(Stringer); ok { 
     fmt.Println("i can be asserted to Stringer") 
    } 
    if _, ok := i.(Byter); ok { 
     fmt.Println("i can be asserted to Byter") 
    } 
    if _, ok := i.(Stringbyter); ok { 
     fmt.Println("i can be asserted to Stringbyter") 
    } 
    if _, ok := i.(*Polymorphic); ok { 
     fmt.Println("i can be asserted to *Polymorphic") 
    } 
    if _, ok := i.(int); ok { 
     fmt.Println("i can be asserted to int") // Never runs 
    } 
} 

アサーションのintは、コンクリートタイプ(インターフェイスタイプとは対照的)であるため、失敗します。 ichは*Polymorphicではありません。

0

インターフェイスタイプから基になるタイプのみアサーションを入力できます。この場合、intintからfloat64