繁体   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