2015-05-11 6 views
7

, bir şeyin bir işaretçi nil arayüzü dönüştürmeye çalışırken aşağıdaki hata nedeniyle başarısız: Burada interface conversion: interface is nil, not *main.NodeNULL arabirimini Golang'daki bir şeyin işaretçisine dönüştürün? Aşağıdaki kod parçası olarak

type Nexter interface { 
    Next() Nexter 
} 

type Node struct { 
    next Nexter 
} 

func (n *Node) Next() Nexter {...} 

func main() { 
    var p Nexter 

    var n *Node 
    fmt.Println(n == nil) // will print true 
    n = p.(*Node) // will fail 
} 

Play bağlantısı: https://play.golang.org/p/2cgyfUStCI

Neden bu tam başarısız oluyor? Bu

n = (*Node)(nil) 

yapmak tamamen mümkün, bu yüzden bir nil arayüzünden başlayarak benzer bir etkiyi elde edebilirsiniz nasıl merak ediyorum. (Sadece bir arabirim) statik tip Nexter bir değişken birçok farklı dinamik türleri değerlerini tutabilir çünkü

cevap

21

budur. Nexter uygulayan *Node beri

Evet

, senin p değişken tip *Node bir değer tutabilir, ancak aynı zamanda Nexter uygulamak hangi diğer türleri tutabilir; ya da hiçbir şey hiçbir şekilde ( nil değeri) tutabilir. senin durumunda

x.(T) asserts that x is not nil and that the value stored in x is of type T .

Ama xnil geçerli: spec alıntı çünkü Type assertion burada kullanılamaz. Ve tür onaylama false ise, çalışma zamanı panik olur.

var p Nexter = (*Node)(nil) 

Programınız çalışacak ve tipi iddiası başarılı:

sizinle p değişkeni başlatmak için programınızı değiştirirseniz

. Bunun nedeni, bir arabirim değerinin aslında bir çifti (value, dynamic type) biçiminde tutmasıdır ve bu durumda sizin p nil olmayacaktır, ancak bir çift (nil, *Node); Ayrıntılar için bkz. The Laws of Reflection #The representation of an interface. Ayrıca arayüz türleri nil değerlerini işlemek istiyorsanız

, böyle açıkça olup olmadığını kontrol edebilirsiniz:

if p != nil { 
    n = p.(*Node) // will not fail IF p really contains a value of type *Node 
} 

Ya da daha: kullanmak özel "virgülle ok" formu:

// This will never fail: 
if n, ok := p.(*Node); ok { 
    fmt.Printf("n=%#v\n", n) 
} 

"Virgül-Tamam" formunu kullanarak:

The value of ok is true if the assertion holds. Otherwise it is false and the value of n is the zero value for type T . No run-time panic occurs in this case.

İlgili konular