簡體   English   中英

將結構組合傳遞給 function

[英]Passing struct composites into function

需要一些幫助來理解 golang。

來自 C++ 使用基礎 class 這是微不足道的。 在 Go 中,使用結構組合,它可以正常工作,直到我需要 function 采用“基礎”結構。 我知道它不是真正的基礎 class,但是在從派生的基礎 class 的字段中分配值時,它工作正常。 但是我不能將Dog傳遞給需要Wolf的 function 。

package main
    
import "fmt"
    
type Wolf struct {
    ID     string
    Schema int
}
    
type Dog struct {
    Wolf
}
    
type Dingo struct {
    Wolf
}
    
func processWolf(wolf Wolf) {
    fmt.Println(wolf.ID, wolf.Schema)
}
    
func main() {
    porthos := Dog{}
    porthos.ID = "Porthos"  // works fine able to set field of Wolf
    porthos.Schema = 1      // works fine
    
    aussie := Dingo{}
    aussie.ID = "Aussie"  // works fine
    aussie.Schema = 1     // works fine
    
    fmt.Println(porthos.ID, porthos.Schema)
    fmt.Println(aussie.ID, aussie.Schema)

    processWolf(porthos) << fails here
    processWolf(aussie) << fails here
    
}

processWolf function 接受Wolf參數,因此您必須傳遞Wolf 由於兩個結構都嵌入了Wolf ,您可以執行以下操作:

processWolf(porthos.Wolf) 
processWolf(aussie.Wolf) 

因為當你將Wolf嵌入Dog時, Dog會得到Wolf的所有方法,再加上Dog有一個名為Wolf的成員。

當我最初發布問題時,我試圖簡化問題陳述,也許太多了,Serdar 先生很友好地回答了這個問題,但對我的問題沒有幫助。 在深入研究了 gophers 的語言之后,我遇到了一個使用 interface{} 來解決這個問題的解決方案。 我修改了我的 mongo 代碼並且它正在工作,盡管我可能會說它看起來不像其他語言傳遞引用那么簡單。

// FindAll retrieves one object from the collection
func FindAll(collection *mongo.Collection, filter bson.M, resultSet interface{}) error {

    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Seconds)
    defer cancel()

    cursor, err := collection.Find(ctx, filter)
    if err != nil {
        return err
    }

    defer cursor.Close(ctx)

    objects := reflect.ValueOf(resultSet).Elem()

    for cursor.Next(ctx) {

        obj := reflect.New(objects.Type().Elem())

        err = cursor.Decode(obj.Interface())

        if err != nil {
            log.Panicln("FindAll:", err.Error())
            // assuming that an interface is out of alignment and need to know ASAP.
        }

        objects = reflect.Append(objects, obj.Elem())
    }

    reflect.ValueOf(resultSet).Elem().Set(objects)

    return nil
}

然后使用

    var dogs []Dog
    if err := database.FindAll(houseCollection, bson.M{}, &dogs); err != nil {
        return nil, err
    }

    println(dogs)
    var dingos []Dingo
    if err := database.FindAll(houseCollection, bson.M{}, &dingos); err != nil {
        return nil, err
    }

    println(dingos)

如果 Dog 和 Dingo 必須與基礎 class 相關聯。 但我真的覺得 Golang 的設計者做了一些我還沒有理解的奇怪的轉折。 雖然追地鼠很開心。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM