将结构组合传递给函数
Passing struct composites into function
需要一些帮助来理解 golang。
来自使用基数的 C++ class 这是微不足道的。在 Go 中,使用结构组合,直到我需要具有采用“Base”结构的函数为止,它都可以正常工作。我知道它不是真正的基础 class,但是当从派生的基础 class 的字段中分配值时,它工作正常。但是我无法将 Dog
传递给采用 Wolf
.
的函数
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
函数接受一个Wolf
参数,所以你必须传递一个Wolf
。由于两个结构中都嵌入了 Wolf
,您可以这样做:
processWolf(porthos.Wolf)
processWolf(aussie.Wolf)
因为当你将 Wolf
嵌入到 Dog
中时,Dog
获得了 Wolf
的所有方法,加上 Dog
有一个名为 [=12 的成员=].
当我最初发布这个问题时,我试图简化问题陈述,也许太多了,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的设计者做了一些我还没有理解的奇怪的转折。虽然追地鼠很开心。
需要一些帮助来理解 golang。
来自使用基数的 C++ class 这是微不足道的。在 Go 中,使用结构组合,直到我需要具有采用“Base”结构的函数为止,它都可以正常工作。我知道它不是真正的基础 class,但是当从派生的基础 class 的字段中分配值时,它工作正常。但是我无法将 Dog
传递给采用 Wolf
.
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
函数接受一个Wolf
参数,所以你必须传递一个Wolf
。由于两个结构中都嵌入了 Wolf
,您可以这样做:
processWolf(porthos.Wolf)
processWolf(aussie.Wolf)
因为当你将 Wolf
嵌入到 Dog
中时,Dog
获得了 Wolf
的所有方法,加上 Dog
有一个名为 [=12 的成员=].
当我最初发布这个问题时,我试图简化问题陈述,也许太多了,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的设计者做了一些我还没有理解的奇怪的转折。虽然追地鼠很开心。