如何製作一個接受任何結構的通用結構?
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
介面。
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中文網其他相關文章!