Wie implementiert man allgemeine Funktionen gekapselter Modelle in Golang?

PHPz
Freigeben: 2024-02-11 23:42:09
nach vorne
1066 Leute haben es durchsucht

Wie implementiert man allgemeine Funktionen gekapselter Modelle in Golang?

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.

Frageninhalt

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)
}
Nach dem Login kopieren

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)
}
Nach dem Login kopieren

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)
}
Nach dem Login kopieren

Aber es kann nicht gefunden werdenm.models,我的意思是teachers.teachersclasses.classesKann nicht verwendet werden

Bitte sagen Sie mir, was in diesem Fall zu tun ist

Umgehung

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
}
Nach dem Login kopieren

Anrufbeispiel:

ch, n, err := readdata[class.class]("db/student_class.json", "classes")

// or

ch, n, err := readdata[teacher.teacher]("db/teachers.json", "teachers")
Nach dem Login kopieren

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]
}
Nach dem Login kopieren

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")
}
Nach dem Login kopieren

Dann ist der Aufruf ganz einfach:

classes, err := ReadData[class.Class]("db/student_class.json")

// or

teachers, err := ReadData[teacher.Teacher]("db/teachers.json")
Nach dem Login kopieren

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!