2017-12-25 4 views
-2

Ich habe reading about Typ Alias ​​und komponierte Strukturen in Golang gewesen. Ich möchte in der Lage sein, zwei Strukturen zu haben, die strukturell identisch sind, aber leicht zwischen einander umgewandelt werden können.Convert Komponiert Typ in Golang

Ich habe eine übergeordnete Struktur wie folgt definiert:

type User struct { 
    Email string `json:"email"` 
    Password string `json:"password"` 
} 

Und eine bestandene Struktur wie folgt definiert:

type PublicUser struct { 
    *User 
} 

Ich würde erwarten, dass, wenn ich definieren eine User:

a := User{ 
     Email: "[email protected]", 
     Password: "1234", 
    } 

Ich könnte dann die folgende Umwandlung durchführen:

b := (a).(PublicUser) 

aber es funktioniert nicht mit einer ungültigen Typ Behauptung:

invalid type assertion: a.(PublicUser) (non-interface type User on left) 

Wie kann ich zwischen strukturell ähnlichen Typen in Go-Format konvertieren?

https://play.golang.org/p/I0VqrflOfXU

+0

"Ich habe eine Elternstruktur definiert". Nein, tust du nicht. Auf Go gibt es keine Eltern/Kind-Beziehung. Vergiss das jetzt und für immer. Über Kompositionen als Eltern/Kind nachzudenken ist nicht hilfreich. – Volker

+0

Hey OP, ist es wichtig zu erklären, warum du entschieden hast, dass die Antwort nicht das war, was du wolltest? Du hast es einmal akzeptiert, also bin ich neugierig, ob du inzwischen Informationen gefunden hast –

Antwort

1

Typ Behauptungen in Go können Sie tippen in eine der Schnittstelle konkreter, nicht in structs:

Eine Art Behauptung ermöglicht den Zugang zu einem darunter liegenden Betonwert Schnittstelle Wert.
https://tour.golang.org/methods/15

jedoch mit leichten Modifikationen Dieser Code funktioniert und verhält sich wahrscheinlich wie man erwarten würde:

package main 

import (
    "fmt" 
) 

type User struct { 
    Email string `json:"email"` 
    Password string `json:"password"` 
} 

type PublicUser User 

func main() { 
    a := User{ 
     Email: "[email protected]", 
     Password: "1234", 
    } 
    fmt.Printf("%#v\n", a) 
    // out: User{Email:"[email protected]", Password:"1234"} 

    b := PublicUser(a) 
    fmt.Printf("%#v", b) 
    // out PublicUser{Email:"[email protected]", Password:"1234"} 
} 

Hier PublicUser eine Neudefinition des User Typ ist; Am wichtigsten ist, dass es ein eigenständiger Typ ist, der die Felder teilt, aber nicht den Methodensatz von User (https://golang.org/ref/spec#Type_definitions).

Dann können Sie einfach den Konstruktor PublicUser Typ verwenden, wie Sie es möglicherweise mit string/[]byte Konvertierungen getan haben: foo := []byte("foobar").

Wenn auf der anderen Seite waren Sie eine tatsächliche type alias (type PublicUser = User) die Ausgabe zu verwenden, wird für beide Instanzen User als Dateityp: PublicUser ist nur ein neuer Name für die alte Sache, nicht eine neue Art.