将结构数组传递给Go中的函数

时间:2016-05-09 11:11:58

标签: go

我有一个从某个XML文件解析的对象。它有像这样的结构类型

type Report struct {
    Items []Item `xml:......`
    AnotherItems []AnotherItem `xml:......`
}
type Item struct {
    Name string
}
type AnotherItem struct {
    Name string
}
func (Item *Item) Foo() bool {
    //some code here
}
func (AnotherItem *AnotherItem) Foo() bool {
    //another code here
}

对于每件物品,我必须这样做:

func main(){
    //some funcs called to get the report object
    doSmth(report.Items)
    doSmth(report.AnotherItems)
}
func doSmth(items ????){
    for _, item : range items {
        item.Foo()
    }
}

由于我有不同的项目具有相同的功能我想只有一个doSmth所以我不能只做doSmth(items []Item) 问题是 - 我该怎么写而不是" ????"让这个工作? 我将report.Items传递给doSmth()的唯一方法是

func doSmth(items interface{})

但是它给我一个错误"不能超过项目范围(类型接口{})" 如果不是迭代我只是把smth像

func doSmth(items interface{}){
    fmt.Println(items)
}

程序打印我的项目列表

4 个答案:

答案 0 :(得分:0)

<击> 将????替换为[]ItemGo Playground。它与结构report.Items中定义变量Report的方式相同。

好的,是的确改变了这个问题。我立刻想到的是你只需要在Itemer的函数定义中创建[]ItemerdoSmth等界面:

type Itemer interface {
    Foo() bool
} 

func doSmth(items []Itemer) {
    ...
}

不幸的是this does not seem to be possible。然后我尝试了一些其他的排列,包括使用interface{}[]interface{}以及可变参数函数,我无法使用任何东西。

doing some research之后,事实证明Go不会转换切片的类型。即使切片的每个元素都是接口的实例,例如Itemerinterface{},它仍然不会这样做。 我无法重新找到源但显然这是因为必须创建一个新的切片,并且每个元素必须从旧切片到新切片分别进行类型转换:https://stackoverflow.com/a/7975763/2325784

对我而言,这表明诸如doSmth之类的功能是不可能的。

我唯一能建议的是重构代码。如果您愿意发布有关FoodoSmth的更多信息,我可以尝试提供帮助。

答案 1 :(得分:0)

您需要为此范围使用可变参数函数:

func main(){
    //some funcs called to get the report object
    doSmth(report.Items)
}
func doSmth(items ...report.Items){
    for _, item := range items {
        item.Foo()
    }
}

答案 2 :(得分:0)

编辑: Nvm,这不行。忘记了go没有继承的事实。

您可以将数组转换为切片,并使该函数将切片作为参数。

db.Test.aggregate( [ 
{ $unwind : { path: "$Items",includeArrayIndex: "arrayIndex"} } ,
{ $match:  { $and: [
        {$or: [ { CreatedOn: { $gt: ISODate("2015-11-22T00:00:00Z")} }, {UpdatedOn: { $gt: ISODate("2015-11-22T00:00:00Z") } } ] },
        {$or: [ { CreatedOn: { $lt: ISODate("2016-05-09T00:00:00Z")} }, {UpdatedOn: { $lt: ISODate("2016-05-09T00:00:00Z") } } ] }
                   ] }
 }] )

答案 3 :(得分:0)

您可以使用基本的数组概念像这种类型的结构值数组那样调用: 在此示例中,[] item应该称为item.Item [i] .Unitprice

我希望你会有所想法


type UserItem struct {
    UniqueID string `json:"uniqueID" bson:"uniqueID,omitempty"`
    Item     []Item
}

//Item : ""
type Item struct {
    ProductName   string  `json:"productName" bson:"productName,omitempty"`
    UnitPrice     float64 `json:"unitPrice" bson:"unitPrice,omitempty"`
    Quantity      float64 `json:"quantity" bson:"quantity,omitempty"`

//main : ""
func main(){
    for i := 0; i < len(item.Item); i++ {
        SubTotal := item.Item[i].UnitPrice * item.Item[i].Quantity
        TotalTax := (item.Item[i].TaxPercentage / 100)
        TotalTax = SubTotal * TotalTax
        Tax := SubTotal + TotalTax
        fmt.Println(Tax)
}