亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何制作一個類的對象并為結構設置吸氣劑?

如何制作一個類的對象并為結構設置吸氣劑?

Go
HUH函數 2022-10-24 09:52:44
我最近開始工作,golang因此很難理解如何實現我能夠在Javaor中輕松完成的相同事情C#。我正在嘗試創建一個configmanager類對象,當第一次configmanager調用類時,它應該初始化我的所有配置并將其存儲在內存中的某個結構對象中。然后我應該可以訪問configmanager對象,并且應該能夠使用一些 getter 從我的主函數訪問所有這些配置?下面是我的configmanager圍棋課?,F在很簡單,使其更容易理解。package configimport (    "encoding/json"    "fmt"    "io/ioutil"    "github.com/david/internal/utilities")type ClientMetrics struct {    ClientMetrics []ClientMetric `json:"clientMetrics"`}type CustomerData struct {    Process []string `json:"Process"`    Mat     []string `json:"Mat"`}type ClientMetric struct {    ClientID     int          `json:"clientId"`    CustomerData CustomerData `json:"customerData,omitempty"`    LegCustomer  []int        `json:"legCustomer"`    OtherIds     []int        `json:"otherIds,omitempty"`    CatID        int          `json:"catId,omitempty"`}func Init(root string) (err error) {    files, err := utilities.FindFiles(root, "process-data.json")    if err != nil {        return fmt.Errorf("cannot find process-data.json file: %v", err)    }    for _, file := range files {        body, err := ioutil.ReadFile(file)        if err != nil {            return fmt.Errorf("unable to read file: %v", err)        }        var auto ClientMetrics        json.Unmarshal(body, &auto)    }    return nil}這是我在我的主要功能中使用它 - 這只是基本代碼,只是為了演示我在做什么,但這不是production現成的代碼。package mainimport (    "github.com/david/internal/config")func main() {    root := "/home/Configurations"    config.Init(root)  //}在我上面的Init函數中,process-data.json如果文件在磁盤上,我會找到它,然后通過將其反序列化為ClientMetrics對象將其加載到內存中。如上所示,一切正常。問題陳述由于我來自背景Java,C#所以我的困惑是如何創建一個configmanager類對象,以及如何在我第一次調用時初始化我的所有配置,并且還可以使用一些 getterconfigmanager訪問結構。ClientMetrics在 Java 和 C# 中,我曾經使用構造函數來初始化所有這些東西,然后使用一些 getter 來訪問配置。我應該如何在 golang 中做同樣的事情。我的主要困惑是我們在 go 中是否有構造函數,我應該如何讓 getter 在我的 main 函數中訪問 struct 對象?我只是在尋找更好的設計,我應該如何在 golang 中完成我的上述代碼?
查看完整描述

3 回答

?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

這個問題很難回答,因為你有點忘了以明確的方式問一個問題,所以我將根據你寫的內容提取一個問題來開始我的回答。我相信我們可以這樣做:


問題陳述


[...]我的困惑是如何創建一個configmanager類對象以及我應該如何在我第一次調用時初始化我的所有配置,configmanager并且還可以使用一些 getter 訪問ClientMetricsstruct


我相信這里真正的問題是“我如何將讀取和解組文件的關注與存儲結果以供我的程序使用的關注區分開來?”。


通過將事物分解為多個函數/方法來分離關注點是很常見的,您已經在某種程度上做到了這一點。然而,存儲嚴格來說是類型的問題,所以我們需要一種能夠保存結果的類型。我將利用這個機會Manager從類型名稱中省略這個詞,因為它所做的只是提供無用的抽象。這種類型不管理配置。它是配置,因為它包含所有配置。


type Config struct {

    ClientMapConfigs   []ClientMapConfig

    DataMapConfigs     []DataMapConfig

    ProcessDataConfigs []ProcessDataConfig

}

請注意,這些字段以大寫字母開頭,使其公開。這表明其中可能存在廢話,因為沒有任何內容可以防止寫入,這與我們從文件中讀取這些數據的事實一致。正確的程序必須在使用之前驗證這些數據。然后,您可以在變量名稱中傳達已驗證數據的有效性。


func main() {

    validConfig := getValidConfig("path/to/dir")

    // ...

}


func getValidConfig(configDirectoryPath string) *Config {

    config, err := NewConfigFromConfigDirectory(configDirectoryPath)

    if err != nil {

        log.Printf("Failed to read config from dir '%s': %v\n", configDirectoryPath, err)

        os.Exit(1)

    }

    if err = ValidateConfig(config); err != nil {

        log.Printf("Config from dir '%s' failed to validate: %v\n", configDirectoryPath, err)

        os.Exit(1)

    }

}


func NewConfigFromConfigDirectory(configDirectoryPath string) *Config {

    // <- read individual configs and add to slices here


    return &Config{ // This is the closest to a "constructor" that Go has.

        ClientMapConfigs: clientMapConfigs,

        DataMapConfigs: dataMapConfigs,

        ProcessDataConfigs: processDataConfigs,

    }

}

請注意,驗證和讀取配置的函數不需要接收器,即成為結構的方法。它們可以作為獨立功能使用,直到您的需求發生變化,需要為任一邏輯引入狀態性。


此外,我在這里對錯誤情況使用退出代碼1,因為 Golang2在程序因恐慌而終止時使用代碼。前者可以被認為是環境問題,而后者則表明程序本身存在問題。這是一個有用的區別,并且與您可能從 Java 中知道的語義Exception相一致。RuntimeException


查看完整回答
反對 回復 2022-10-24
?
GCT1015

TA貢獻1827條經驗 獲得超4個贊

我認為問題在于您從 Java/C# 的角度看待 Go,因此難以理解這些特性。如果您有時間,那么我建議您在開始編碼之前先閱讀一些 Go 教程或書籍(這個非常好:https ://www.amazon.com/Programming-Language-Addison-Wesley-Professional-計算/dp/0134190440 )


要直接回答您的問題,您需要做的是創建一個函數,該函數返回指向結構對象的指針(請參見此處的簡單示例:https ://gobyexample.com/structs )


以 ClientMetric 為例:


func NewClientMetric(ClientID int, CustomerData CustomerData, LegCustomer []int, OtherIds []int, CatID int) (*ClientMetric, error) {


//validate your inputs

//in case of errors, create and error message in the variable err and then: return nil, err

//other code which would go into a typical constructor would go here


return &ClientMetric{ClientID,CustomerData, LegCustomer, OtherIds, CatID}, nil

}

在這種情況下,該函數NewClientMetric是構造函數,它返回一個指向新創建對象的指針/引用。它還返回一個錯誤對象,這和說構造函數拋出異常是一樣的。正如您需要在 Java 中使用 try/catch 一樣,您需要檢查以處理此函數返回的 err 變量。


您需要為每種類型創建類似的功能。


至于 getter 和 setter,一般來說,在 Go 中應該避免這種情況。您可以直接訪問結構的屬性。僅當您要在返回屬性之前對屬性執行某些操作時,函數(如 getter)才有用。像這樣的東西:


type Customer struct {

FirstName string

LastName string

}


func (this *Customer) GetFullName() string {

return this.FirstName + " " + this.LastName

}

然后可以像這樣訪問這些:


var customer *Customer

customer = &Customer{"John","Smith")

fmt.Println(customer.FirstName)

fmt.Println(customer.LastName)

fmt.Println(customer.GetFullName())

請注意,以大寫字母開頭的屬性、函數和方法是公共的,其他的是私有的。如果FirstName寫為firstName,則在聲明它的包之外將無法訪問它。


請注意,如果指針為 null/nil,我不會檢查錯誤,但始終建議這樣做。


查看完整回答
反對 回復 2022-10-24
?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

我可以說 10 個不同的配置(文件),每個配置都可以有自己的結構,因為它是不同的配置,所以我需要為它們有單獨的結構

這看起來像動態 JSON 結構解組,這是由John Asmuth在2015 年在使用混合結構進行解碼時提出的

您可以在此處運行以下示例。

type Dog struct {

  Name     string

  Frisbees int

}

type Cat struct {

  Name    string

  Strings int

}

type RawAnimal struct {

  Type string

  Cat

  Dog

}

type Animal RawAnimal

func (a *Animal) UnmarshalJSON(data []byte) error {

  if err := json.Unmarshal(data, (*RawAnimal)(a)); err != nil {

    return err

  }

  switch a.Type {

  case "cat":

    return json.Unmarshal(data, &a.Cat)

  case "dog":

    return json.Unmarshal(data, &a.Dog)

  }

  return fmt.Errorf("unknown type %q", a.Type)

}

從那里,您的 ConfigManager 將根據讀取的原始 JSON 實例化正確的 Config 結構。


查看完整回答
反對 回復 2022-10-24
  • 3 回答
  • 0 關注
  • 172 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號