Maison  >  Article  >  développement back-end  >  Comment implémenter les fonctions communes des modèles encapsulés dans Golang ?

Comment implémenter les fonctions communes des modèles encapsulés dans Golang ?

PHPz
PHPzavant
2024-02-11 23:42:091070parcourir

Comment implémenter les fonctions communes des modèles encapsulés dans Golang ?

Dans Golang, les fonctions communes des modèles encapsulés peuvent être implémentées en utilisant des structures et des méthodes. Une structure est un type de données personnalisé qui peut être utilisé pour encapsuler des données et des méthodes associées. Les méthodes sont des fonctions associées à une structure, et les membres de la structure sont accessibles et manipulables au sein de la méthode. En définissant les fonctions sous forme de structures, nous pouvons associer des fonctions à des structures spécifiques pour implémenter des opérations communes dans des modèles encapsulés. En Golang, nous pouvons utiliser des récepteurs pour spécifier la structure à laquelle appartient la méthode. Le récepteur peut être de type valeur ou de type pointeur, choisissez le type de récepteur approprié en fonction de vos besoins. En définissant la méthode de structure, nous pouvons implémenter des opérations courantes dans le modèle encapsulé, telles que l'obtention ou la définition de valeurs de champ, l'exécution d'opérations spécifiques, etc. De cette façon, nous pouvons accéder et exploiter les données encapsulées en appelant les méthodes de la structure, obtenant ainsi un code plus flexible et réutilisable.

Contenu des questions

J'ai 2 colis comme modèles :

Catégorie :

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)
}

Professeur :

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)
}

Vous pouvez donc voir que la fonction readdata est exécutée à plusieurs reprises. Maintenant, je peux utiliser class.readdata()teacher.readdata() pour appeler des données depuis la chaîne.

Comment écrire une fonction readdata() destinée à être utilisée par deux packages ?

J'ai essayé de créer un package de base en utilisant des génériques comme celui-ci :

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)
}

Mais il est introuvablem.models,我的意思是teachers.teachersclasses.classesNe peut pas être utilisé

Veuillez me dire quoi faire dans ce cas

Solution de contournement

Utilisez des génériques (introduits dans go 1.18). Créez une fonction readdata() avec des types de paramètres représentant les valeurs à décoder de json et transmises sur le canal.

Remarque : vous devez rechercher les bugs et les signaler (y compris ceux de 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
}

Exemple d'appel :

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

// or

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

Veuillez noter que renvoyer le nombre de valeurs lues doit être redondant. Puisque vous avez fermé correctement le canal renvoyé, l'appelant peut utiliser for range sur le canal renvoyé, qui recevra correctement toutes les valeurs qui y sont envoyées, puis se terminera.

Notez également que puisque toutes les valeurs sont prêtes (décodées) lors du retour au canal, cette simultanéité est redondante et ne fait que réduire l'efficacité. Vous disposez d'une tranche de valeurs décodées, renvoyez-la simplement et laissez l'appelant choisir comment il souhaite la gérer (simultanée ou non simultanée).

Donc votre readdata() devrait ressembler à ceci :

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]
}

Notez également que si l'objet json d'entrée n'a qu'un seul champ, il n'est pas nécessaire de passer fieldname,您可以从解码后的 m pour obtenir la valeur dans la carte, comme ceci :

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")
}

Alors l'appeler est simple :

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

// or

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer