【问题标题】:Passing array of structs to a function in Go将结构数组传递给 Go 中的函数
【发布时间】:2016-05-09 11:11:57
【问题描述】:

我有一个从某个 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)
}

程序打印我的项目列表

【问题讨论】:

  • 你试过(items ...)吗?
  • 编译器说final argument in variadic function missing type

标签: go


【解决方案1】:

???? 替换为[]ItemGo Playground。这与在结构Report 中定义变量report.Items 的方式相同。

好的,是的,这确实改变了问题。我马上想到的就是,你只需要创建一个Itemer这样的接口,并在doSmth的函数定义中有[]Itemer

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 的更多信息,我可以尝试提供帮助。

【讨论】:

  • 抱歉,我忘记了重要的细节,为什么我不能在添加到问题的声明中使用项目类型
【解决方案2】:

您需要为此作用域使用可变参数函数:

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

【讨论】:

  • 抱歉,我忘记了重要的细节,为什么我不能在添加到问题的声明中使用项目类型
  • 这在语法上不正确:undefined: report in report.Items。此外,如果您想使用可变参数函数,您需要像 doSmth(report.Items...) 一样调用 doSmth
  • report 变量创建较早的report := getReport()
  • 其实这个错误来自函数定义而不是函数被调用的地方:play.golang.org/p/rELz-hXgGC.
【解决方案3】:

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

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

names := []string{"leto", "paul", "teg"}
process(names[:])

func process(names []string) {
  ...
}

【讨论】:

    【解决方案4】:

    您可以使用基本数组概念调用这种类型的结构值数组: 在这个例子中,[]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)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 2011-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多