首頁 > 後端開發 > Golang > golang中封裝模型的常用函數如何實現?

golang中封裝模型的常用函數如何實現?

PHPz
發布: 2024-02-11 23:42:09
轉載
1128 人瀏覽過

golang中封裝模型的常用函數如何實現?

在Golang中,封裝模型的常用函數可以透過使用結構體和方法來實現。結構體是一種自訂的資料類型,可以用來封裝相關的資料和方法。方法是與結構體關聯的函數,可以在方法內部存取和操作結構體的成員。透過將函數定義為結構體的方法,我們可以將函數與特定的結構體關聯起來,實現封裝模型中的常用操作。在Golang中,我們可以使用接收者來指定方法所屬的結構體。接收者可以是值類型或指標類型,根據需要選擇合適的接收者類型。透過定義結構體的方法,我們可以在封裝模型中實現常見的操作,例如取得或設定欄位的值,執行特定的操作等。這樣,我們可以透過呼叫結構體的方法來存取和操作封裝的數據,實現更靈活和可重複使用的程式碼。

問題內容

我有 2 個套件作為模型:

類別:

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)
}
登入後複製

老師:

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)
}
登入後複製

因此您可以看到 readdata 函數被重複執行。現在我可以使用 class.readdata()teacher.readdata() 從通道呼叫資料。

如何寫一次 readdata() 函數供兩個套件使用?

我嘗試建立一個使用泛型的基礎包,如下所示:

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)
}
登入後複製

但是找不到m.models,我的意思是teachers.teachersclasses.classes無法使用

請告訴我在這種情況下該怎麼辦

解決方法

使用泛型(go 1.18 中引入)。建立一個 readdata() 函數,使用參數類型表示要從 json 解碼並在通道上傳遞的值。

注意:您應該檢查錯誤並報告錯誤(包括來自 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
}
登入後複製

呼叫範例:

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

// or

ch, n, err := readdata[teacher.teacher]("db/teachers.json", "teachers")
登入後複製

請注意,傳回讀取值的數量應該是多餘的。由於您正確關閉了返回的通道,呼叫者可以在返回的通道上使用 for range ,該通道將正確接收在其上發送的所有值,然後終止。

另請注意,由於返回通道時所有值都已準備就緒(已解碼),因此這種並發性是多餘的,只會降低效率。您有一個解碼值的切片,只需返回它並讓呼叫者選擇它希望如何處理它(並發或非並發)。

所以你的 readdata() 應該如下圖:

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]
}
登入後複製

另請注意,如果輸入json 物件只有一個字段,則無需傳遞fieldname,您可以從解碼後的m 映射中取得值,如下所示:

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")
}
登入後複製

然後呼叫它很簡單:

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

// or

teachers, err := ReadData[teacher.Teacher]("db/teachers.json")
登入後複製

以上是golang中封裝模型的常用函數如何實現?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板