首頁  >  文章  >  後端開發  >  接受任何結構的通用結構

接受任何結構的通用結構

王林
王林轉載
2024-02-06 08:21:04837瀏覽

接受任何結構的通用結構

問題內容

如何製作一個接受任何結構的通用結構?

package model

type model struct {
    m *interface{}
}

func (m *model) Select(){
    
}

type (
    field struct {
        table   string
        field   string
    }
    fields  map[string]field
)

type User struct {
    schema      string
    fields      fields
}

func NewUser() *interface{} {
    model_user := &User{
        schema: "main",
        
        fields: fields{
            "id":           field{"user","id"},
            "client_id":    field{"user","client_id"},
            "email":        field{"user","email"},
        },
    }
    return model(model_user)
}

主要內容

NewUser()

錯誤

cannot convert model_user (variable of type *User) to type model

正確答案


根據定義,model 結構似乎存在,用於將Select() 函數新增(或嘗試新增)到模型中包含的值。

即您似乎想要某種類型提供呼叫Select() 的能力,並對任何任意類型的值執行某些操作(大概在Select() 實作中使用某種形式的類型開關)。

如果是這樣,那麼您最好直接使用 interface 並消除 model 中間人:

type Selectable interface {
  Select()
}

type User struct {
  //...
}

func (u *User) Select() {
   // implement Select as appropriate for the User type
}

func NewUser() *User {
  return &User{
     // ...
  }
}

func Select(s Selectable) {
   s.Select()
}

func main() {
   u := NewUser()
   Select(u)
}

您會發現Select(Selectable) 函數是多餘的(您可以直接呼叫u.Select() ;提供它只是為了說明在需要Selectable 的情況下可以使用任何類型的值,前提是該類型實作了Selectable 介面。

GoLang 中的 interfaces 提供鴨子類型 - 如果一個類型實現了接口的契約,那麼它就實現了該接口,即使該具體類型事先不知道任何正式的接口定義。即「如果它看起來像鴨子並且嘎嘎叫起來像鴨子,那麼它就是鴨子」。

如果目的是從User 類型(或其他類型)中刪除Select()ing 的邏輯,並將其隔離在單獨的「選擇器」中,那麼可以透過刪除model 中介並簡單地實作一個func 來再次實現這一點執行類型轉換:

<code>func Select(v any) error {
   switch v := v.(type) {
      case *User:
         // ... implement for *User or call some private fn which encapsulates this behaviour
      default:
          return errors.New("value cannot be Select()ed")
    }
}
</code>

以上是接受任何結構的通用結構的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除