2015-02-13 3 views
12

Ich kann in Golang mit Zeiger und Wert einbetten. Durch ZeigerEmbedding in Go mit Zeiger oder mit Wert

type Bitmap struct{ 
    data [4][4]bool 
} 

type Renderer struct{ 
    *Bitmap 
    on uint8 
    off uint8 
} 

von Wert

type Bitmap struct{ 
    data [4][4]bool 
} 

type Renderer struct{ 
    Bitmap 
    on uint8 
    off uint8 
} 

Was ist durch Zeiger oder Wert bevorzugen?

+0

Wahrscheinlich eine gute Idee, Ihre Quellen zu zitieren: http://www.hydrogen18.com/blog/golang-embedding.html –

Antwort

16

Kommt drauf an. Hier gibt es mehrere Möglichkeiten.

  • Wenn Renderer nach Wert übergeben wird und die für Bitmap benötigten Methoden auf * Bitmap definiert sind, müssen Sie * Bitmap einbetten.
  • Wenn Renderer als Zeiger übergeben wird, können Sie Bitmap problemlos als Wert einbetten (Zeigermethoden sind in diesem Fall weiterhin verfügbar).
  • Wenn Bitmap über eine Konstruktorfunktion verfügt, die einen Zeiger zurückgibt, und der Nullwert von Bitmap nicht verwendbar ist, möchten Sie * Bitmap einbetten, da Sie kein wertmäßiges Kopieren des Bitmap-Werts unterstützen möchten .
  • Wenn alle Bitmap-Methoden Wertmethoden sind, möchten Sie unbedingt nach Wert einbetten.
  • In dem speziellen Fall, den Sie hier haben, würde ich wahrscheinlich nach Wert einbetten, da der Typ klein ist - es gibt Ihnen Zugriffsorte und weniger Speicherzuweisungen.

    5

    Durch die Einbettung eines Typs möchten Sie normalerweise von der Anrufweiterleitung profitieren. *Bitmap 's method set ist ein Superset von Bitmap' s method set. In den meisten Fällen möchten Sie also *Bitmap einbetten, es sei denn, alle Methoden haben einen Empfänger vom Typ Bitmap oder die Methode leer, in denen Sie die Umleitung vermeiden können.

    0

    Ich habe es auch nützlich gefunden, wenn Sie mehrere Strukturen alle mit dem gleichen eingebetteten Basistyp haben, und Sie eine Hilfsfunktion verwenden möchten, die die Werte der Basisstruktur ändert. Zum Beispiel die folgenden Strukturen gegeben:

    type Base struct { 
        F1 int 
    } 
    
    type A struct { 
        *Base 
        Fa int 
    } 
    
    type B struct { 
        *Base 
        Fb int 
    } 
    

    und die folgende Hilfsfunktion:

    func modstruct(base *Base) { 
        base.F1 = 2 
    } 
    

    alle folgenden Funktionsaufruf kompilieren, und ändern Werte der Struktur:

    base := &Base{} 
    a := &A{Base: &Base{}} 
    b := &B{Base: &Base{}} 
    modstruct(base) 
    modstruct(a.Base) 
    modstruct(b.Base) 
    
    2

    Es scheint so ein Missverständnis von Empfängern zu sein, wie es in Rogs Antwort ausgedrückt wird. Methoden (Empfänger) sind nicht auf einem Zeiger oder einem Typ "definiert", die gleichen Methoden können auf dem Wert des Typs als der Zeiger aufgerufen werden, die Unterschrift des Empfängers bestimmt nur, ob er einen Werttyp oder einen Zeiger auf empfängt Werttyp. Das heißt, func(t *YourType) kann über YourType oder &YourType und umgekehrt mit einem Wertempfänger aufgerufen werden. Ich denke, das sollte klarstellen: So zu der Frage, ob ein Wert oder Zeiger eingebettet werden ... die Referenzialität wird wirklich bestimmt, wie Sie mit dem äußeren Objekt umgehen, wenn Sie einen Zeiger auf die äußere Struktur Sie übergeben Zugriff auf den gleichen eingebetteten Strukturwert haben, wenn Sie den Wert der äußeren Struktur übergeben, soll er auf den "ursprünglichen" zugrunde liegenden Wert der eingebetteten Struktur oder einer Kopie zeigen? Ich denke in den meisten Fällen wollen Sie entweder einen Zeiger einbetten und Zeiger auf Ihre äußere Struktur übergeben oder einen Wert einbetten und Wert Ihrer äußeren Struktur übergeben.