In Golang können gemeinsame Funktionen gekapselter Modelle durch den Einsatz von Strukturen und Methoden implementiert werden. Eine Struktur ist ein benutzerdefinierter Datentyp, der zum Kapseln verwandter Daten und Methoden verwendet werden kann. Methoden sind Funktionen, die einer Struktur zugeordnet sind, und auf die Mitglieder der Struktur kann innerhalb der Methode zugegriffen und diese manipuliert werden. Indem wir Funktionen als Strukturen definieren, können wir Funktionen bestimmten Strukturen zuordnen, um allgemeine Operationen in gekapselten Modellen zu implementieren. In Golang können wir Empfänger verwenden, um die Struktur anzugeben, zu der die Methode gehört. Der Empfänger kann ein Werttyp oder ein Zeigertyp sein. Wählen Sie den geeigneten Empfängertyp entsprechend Ihren Anforderungen aus. Durch die Definition der Strukturmethode können wir allgemeine Vorgänge im gekapselten Modell implementieren, z. B. das Abrufen oder Festlegen von Feldwerten, das Durchführen bestimmter Vorgänge usw. Auf diese Weise können wir auf die gekapselten Daten zugreifen und diese bearbeiten, indem wir die Methoden der Struktur aufrufen, wodurch flexiblerer und wiederverwendbarer Code entsteht.
Ich habe 2 Pakete als Models:
Kategorie:
package class import ( "encoding/json" "student_management/model/base" ) type classes struct { classes []class } type class struct { id int `json:"student_id"` name int `json:"name"` homeroomteacherid int `json:"homeroom_teacher_id"` } func readdata() (chan class, int) { var classes classes bytevalue := base.readjson("db/student_class.json") json.unmarshal(bytevalue, &classes) classchannel := make(chan class) go func () { for i := 0; i < len(classes.classes); i++ { classchannel <- classes.classes[i] } close(classchannel) }() return classchannel, len(classes.classes) }
Lehrer:
package teacher import ( "encoding/json" base "student_management/model/base" ) type teachers struct { teachers []teacher `json:"teachers"` } type teacher struct { base.persions homeroomteacher bool `json:"homeroom_teacher"` } func readdata() (chan teacher, int) { var teachers teachers bytevalue := base.readjson("db/teachers.json") json.unmarshal(bytevalue, &teachers) teacherchannel := make(chan teacher) go func () { for i := 0; i < len(teachers.teachers); i++ { teacherchannel <- teachers.teachers[i] } close(teacherchannel) }() return teacherchannel, len(teachers.teachers) }
So können Sie sehen, dass die Funktion readdata wiederholt ausgeführt wird. Jetzt kann ich class.readdata()
和 teacher.readdata()
verwenden, um Daten vom Kanal abzurufen.
Wie schreibe ich eine readdata()-Funktion zur Verwendung durch zwei Pakete?
Ich habe versucht, ein Basispaket mit Generika wie diesem zu erstellen:
package base func ReadData[Models any, Model any](fileName string, m Models) (chan interface{}, int) { byteValue := ReadJSON(fileName) json.Unmarshal(byteValue, &m) channel := make(chan Model) go func () { for i := 0; i < len(m.Models); i++ { channel <- m.Models[i] } close(channel) }() return channel, len(models.Models) }
Aber es kann nicht gefunden werdenm.models
,我的意思是teachers.teachers
或classes.classes
Kann nicht verwendet werden
Bitte sagen Sie mir, was in diesem Fall zu tun ist
Verwenden Sie Generika (eingeführt in Go 1.18). Erstellen Sie eine readdata()
-Funktion mit Parametertypen, die die Werte darstellen, die aus JSON dekodiert und an den Kanal übergeben werden sollen.
Hinweis: Sie sollten nach Fehlern suchen und diese melden (einschließlich derer von base.readjson()
).
func readdata[t any](filename, fieldname string) (chan t, int, error) { var m map[string][]t bytevalue := base.readjson(filename) if err := json.unmarshal(bytevalue, &wrapper); err != nil { return nil, 0, err } values := m[fieldname] valueschannel := make(chan t) go func() { for _, v := range values { valueschannel <- v } close(valueschannel) }() return valueschannel, len(values), nil }
Anrufbeispiel:
ch, n, err := readdata[class.class]("db/student_class.json", "classes") // or ch, n, err := readdata[teacher.teacher]("db/teachers.json", "teachers")
Bitte beachten Sie, dass die Rückgabe der Anzahl der gelesenen Werte redundant sein sollte. Da Sie den zurückgegebenen Kanal korrekt geschlossen haben, kann der Anrufer for range
auf dem zurückgegebenen Kanal verwenden, wodurch alle darauf gesendeten Werte korrekt empfangen und dann beendet werden.
Beachten Sie außerdem, dass diese Parallelität redundant ist und nur die Effizienz verringert, da alle Werte bereit (dekodiert) sind, wenn sie zum Kanal zurückkehren. Sie haben ein Stück dekodierter Werte. Geben Sie es einfach zurück und lassen Sie den Aufrufer entscheiden, wie es damit umgehen möchte (gleichzeitig oder nicht gleichzeitig).
Ihr readdata()
sollte also so aussehen:
func readdata[t any](filename, fieldname string) ([]t, error) { var m map[string][]t bytevalue := base.readjson(filename) if err := json.unmarshal(bytevalue, &wrapper); err != nil { return nil, err } return m[fieldname] }
Beachten Sie außerdem, dass, wenn das Eingabe-JSON-Objekt nur ein Feld hat, kein fieldname
,您可以从解码后的 m
übergeben werden muss, um den Wert in der Karte zu erhalten, wie folgt:
func readdata[t any](filename string) ([]t, error) { var m map[string][]t bytevalue := base.readjson(filename) if err := json.unmarshal(bytevalue, &wrapper); err != nil { return nil, err } for _, v := range m { return v, nil } return nil, errors.new("empty json") }
Dann ist der Aufruf ganz einfach:
classes, err := ReadData[class.Class]("db/student_class.json") // or teachers, err := ReadData[teacher.Teacher]("db/teachers.json")
Das obige ist der detaillierte Inhalt vonWie implementiert man allgemeine Funktionen gekapselter Modelle in Golang?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!