2012-11-22 14 views
112

Sadece Go tour aracılığıyla çalışıyorum ve işaretçiler ve arabirimler hakkında kafam karıştı. Bu Go kodu neden derlenmiyor?Neden bir * Arabirime bir * Yapısı atayamıyorum?

package main 

type Interface interface {} 

type Struct struct {} 

func main() { 
    var ps *Struct 
    var pi *Interface 
    pi = ps 

    _, _ = pi, ps 
} 

yani Struct eğer neden *Struct bir *Interface olmaz, bir Interface mı?

alıyorum hata iletisi:

prog.go:10: cannot use ps (type *Struct) as type *Interface in assignment: 
     *Interface is pointer to interface, not interface 
+1

See kullanmalıdır da http://stackoverflow.com/q/20874798/260805 o – Ztyx

+0

senin fonk ana() { \t var ps * Struct = new (Struct) \t var pi * Arayüz \t var i Arayüz \t i = ps \t pi 'ile oyun alanı = & i \t fmt.Printf ("% v,% v,% v \ n", * ps, pi, & i) \t i = * ps \t fmt.Printf ("% v,% v,% v \ n", * ps, i) \t _, _, _ = i, pi, ps } 've kendi sonuçlarınızı yapın – Victor

+0

i zenginleştirmek önerebilir ... örtük işaretçiler gibi davranır olabilir arayüzleri benziyor – Victor

cevap

150

Bir arabirimi uygulayan bir yapınız olduğunda, bu yapıya bir işaretçi de bu arabirimi otomatik olarak uygular. Bu nedenle,'a hiçbir şey eklemeyeceğinden, bu işlevlerin prototipinde hiçbir zaman *SomeInterface bulunmaz ve değişken bildirimde böyle bir türe gerek yoktur (bkz. this related question).

Bir arabirim değeri, somut yapının değeri değil (değişken boyutta olduğu için bu mümkün olmaz), ancak bir çeşit işaretçi (daha kesin bir şekilde göstericiye ve türüne işaretçi). Russ Cox tam here açıklar:

Arayüz değerleri arayüzü saklanan türü ve ilişkili veri için bir işaretçi ile ilgili bilgi için bir işaretçiyi veren iki kelimeli çifti olarak temsil edilir.

enter image description here

Bu yüzden Interface ve değil *InterfaceInterface uygulayan bir yapı için bir işaretçi tutmak için doğru türüdür.

Yani basitçe

var pi Interface 
+7

Tamam, bence bu bana mantıklı geliyor. Sadece (bu durumda) neden sadece "var pi * Interface" demek için bir derleme zamanı hatası olmadığını merak ediyorum. –

+1

Açıklamak için daha fazla ayrıntıya girdim. Düzenleme konusuna bakın. Russ Cox'un yazdığım makalesinin okunmasını öneriyorum. –

+0

@SimonNickerson: farklı türlere işaretçiler birbirinin yerine kullanılamaz.Onlar olsaydı, arabirimi uygulayan herhangi bir türdeki herhangi bir değerle işaret edilen şeyin üzerine yazmak için arabirim işaretçisini kullanabilirsiniz, ki bu açıkça iyi değil – newacct

3

Bu ne anlama geldiğini belki de:

package main 

type Interface interface{} 

type Struct struct{} 

func main() { 
     var ps *Struct 
     var pi *Interface 
     pi = new(Interface) 
     *pi = ps 

     _, _ = pi, ps 
} 

Tamam derler. Ayrıca bkz. here.

İlgili konular