2016-10-17 3 views
7

Ich kämpfe mit meinem Lernen von Go.Kann ich in Golang einen Alias ​​eines Typs erstellen?

fand ich diese saubere Implementierung eines Sets in go: gopkg.in/fatih/set.v0, aber ich würde meine Sets mit einem eindeutigen Namen, dass set.Set, etwas zu tun, wie es vorziehen, Benennung:

type View set.Set 

Im Grunde möchte ich meine View Typ zu erben set.Set Methoden. Denn, nun, Viewist einset.Set Deskriptoren. Aber ich weiß, Go ist ziemlich pikant auf Vererbung und Tippen im Allgemeinen.

Denn jetzt habe ich versucht, die folgende irgendwie Vererbung, aber es ist eine Menge Fehler verursachen, wenn einige Funktionen wie func Union(set1, set2 Interface, sets ...Interface) Interface oder func (s *Set) Merge(t Interface) zu verwenden versuchen:

type View struct { 
    set.Set 
} 

würde ich, wenn wissen, es gibt ein Weg, um das zu erreichen, was ich auf eine Go-ähnliche Weise erreichen möchte, oder wenn ich nur versuche, meine guten alten OO-Praktiken auf eine Sprache anzuwenden, die sie ablegt, bitte.

+3

Versuchen Sie nicht zu schreiben Go wie OO-Sprachen mit Vererbung. Es gibt keine Vererbung, also wirst du nur mehr Verwirrung erzeugen. Wenn Sie Methoden und Felder automatisch delegieren möchten, können Sie die Einbettung wie in Ihrem zweiten Beispiel verwenden. Das ist in Ordnung, aber denken Sie daran, dass dies nur eine Form der Komposition ist. – JimB

+0

Also, Ihr Rat verwendet das Original-Set.Set Typ wie ist?Da die Verwendung von Set-Funktionen mit dem eingebetteten Typ so umständlich ist? Es ist nicht so schlimm, ich bin gerade in die Erbschaft getaucht, bevor ich darüber nachgedacht habe, was ich getan habe. –

+2

Wenn Sie interessiert sind, gibt es hier einen guten Artikel zum Thema von William Kennedy: https://www.goinggo.net/2016/10/reducing-type-hierarchies.html – thoeni

Antwort

1

Hinweis, ich denke, die einfachen Aliasing Sie ursprünglich vorgeschlagen syntaktisch gültig ist, obwohl bei der eingestellten Bibliothek einen kurzen Blick gehabt zu haben, anstatt set.Set Aliasing könnte es mehr Sinn, alias set.Interface, zum Beispiel machen:

package main 

import (
    "fmt" 

    set "gopkg.in/fatih/set.v0" 
) 

// View is a type alias for the set.Interface interface 
type View set.Interface 

// Display takes one of our View types in order to print it. 
func Display(view View) { 
    fmt.Println(view.List()) 
} 

func main() { 
    // create our first set.Interface or View 
    v1 := set.New() 
    v1.Add("foo") 

    // create our second set.Interface or View 
    v2 := set.New("bar") 

    // call a set function 
    v3 := set.Union(v1, v2) 

    // call our function that takes a View 
    Display(v3) 
} 

Sie haben vielleicht bemerkt, dass ich irgendwie betrüge, weil ich den aliased-Typ im obigen Code nicht wirklich erwähne, außer dem Parameter Display, über dem Sie notieren, dauert eine View Instanz statt set.Interface. Wenn Sie viele Funktionen haben, die an diesen Dingen arbeiten, dann liest sich das vielleicht expressiver für Ihre Domain.

Beachten Sie, dass unser Typ View ein Alias ​​für einen Schnittstellentyp ist. Daher können Sie keine eigenen Funktionen zu diesem Typ hinzufügen, da Go nicht den Typ eines Schnittstellenempfängers für eine Funktion hat (ich könnte dies falsch ausdrücken)). Damit meine ich, dass man nichts tun kann, wie:

func (v View) Display() string { 
    return v.String() 
} 

Zusammenfassend denke ich Aliasing Dinge in Ordnung ist, kann es interne APIs besser lesbar machen, und Sie können auf den Compiler anlehnen zur Beseitigung bestimmter Klassen Fehler; Dies ermöglicht jedoch nicht das Hinzufügen von Funktionen zum benutzerdefinierten Typ. Wenn dies erforderlich ist, wäre ein alternativer Ansatz erforderlich, entweder Einbettung oder einfache Zusammensetzung (d. H. Ein View hat einen Set).

5

Wenn noch jemand auf diese Frage zurückkommt, werden ab Typ Go 1.9 Aliase unterstützt.

Ein Typ Alias ​​hat die Form: type T1 = T2

So in Ihrem Beispiel können Sie einfach tun type View = set.Set und alles funktioniert, wie Sie wollen.

Verwandte Themen