简体   繁体   English

将结构组合传递给 function

[英]Passing struct composites into function

Need some help understanding golang.需要一些帮助来理解 golang。

Coming from C++ using a base class this is trivial.来自 C++ 使用基础 class 这是微不足道的。 In Go, using struct composition, which works fine up to the point where I need to have function that take the "Base" struct.在 Go 中,使用结构组合,它可以正常工作,直到我需要 function 采用“基础”结构。 I understand that it's not truly a base class, but when comes to assigning values to the fields of the base class from the derived, it works fine.我知道它不是真正的基础 class,但是在从派生的基础 class 的字段中分配值时,它工作正常。 But I cannot pass Dog into a function that takes Wolf .但是我不能将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
    
}

The processWolf function takes a Wolf argument, so you have to pass a Wolf . processWolf function 接受Wolf参数,因此您必须传递Wolf Since both structures have Wolf embedded in them, you can do:由于两个结构都嵌入了Wolf ,您可以执行以下操作:

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

because when you embed Wolf into Dog , Dog gets all the methods Wolf has, plus Dog has a member called Wolf .因为当你将Wolf嵌入Dog时, Dog会得到Wolf的所有方法,再加上Dog有一个名为Wolf的成员。

When i originally posted the question I tried to simplify the problem statement, perhaps too much and Mr. Serdar was kind enough to answer the question, but did not help with my problem.当我最初发布问题时,我试图简化问题陈述,也许太多了,Serdar 先生很友好地回答了这个问题,但对我的问题没有帮助。 After more digging into the lang of gophers, i came across a solution which used interface{} to solve this.在深入研究了 gophers 的语言之后,我遇到了一个使用 interface{} 来解决这个问题的解决方案。 I adapted it my mongo code and it is working, though I might say it does not look as simple as with other language passing references around.我修改了我的 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
}

and then call it using然后使用

    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)

Without Dog and Dingo having to be related with a base class.如果 Dog 和 Dingo 必须与基础 class 相关联。 But I really felt that the designers of Golang made some weird turns that I have yet to understand.但我真的觉得 Golang 的设计者做了一些我还没有理解的奇怪的转折。 Though having fun chasing Gophers.虽然追地鼠很开心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM