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

I have an object parsed from some XML file. It has struct type like this

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
}

For each item i have to do smth like this:

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()
    }
}

Since i have different items with same function i want to have only one doSmth so i can't do just doSmth(items []Item) And the question is - what should i write instead of "????" to get this working? The only way i made it to pass report.Items into doSmth() was

func doSmth(items interface{})

But it throws me an error "cannot range over items (type interface {})" And if instead of iteration i just put smth like

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

program print the list of my items

Replace ???? with []Item: Go Playground. It is just the same as how that variable report.Items is defined in struct Report.

Ok, yes that does change the question. The thing I thought of immediately was that you just needed to create an interface such as Itemer and have []Itemer in the function definition of doSmth:

type Itemer interface {
    Foo() bool
} 

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

Unfortunately this does not seem to be possible. I then tried some other permutations including using interface{}, []interface{} as well as variadic functions and I couldn't get anything to work.

After doing some research it turns out that Go will not convert the type of slices. Even if each element of a slice is an instance of an interface such as Itemer or interface{} it still won't do it. I could not re-find the source but apparently This is due to the fact that a new slice would have to be created and each element would have to be type cast individually from the old slice to the new slice: https://stackoverflow.com/a/7975763/2325784.

To me this suggests that a function such as doSmth is not possible.

The only thing I could suggest is to restructure the code. If you are willing to post more information about Foo and doSmth I can try to help with that.

You need to use variadic function for this scope:

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

EDIT: Nvm, this wont work. Forgot about the fact that go doesn't have inheritance.

You could convert the array into a slice, and make the function take a slice as a parameter instead.

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

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