4

I want to declare a function accept array of interface, such as this:

func (this *CvStoreServiceImpl) setItemList(coll *mgo.Collection, itemList ...interface{}) (err error)

Howerver, when I call this function like as follow failed:

jobList := cvRaw.GetJobList()
this.setItemList(jobColl, jobList...)

here this the error:

cannot use cvRaw.GetJobList() (type []*cv_type.CvJobItemRaw) as type []interface {} in argument to this.setItemList
roger
  • 9,063
  • 20
  • 72
  • 119
  • 3
    Go has no covariant types. You need to stuff your items in jobList into a []interface{} first before passing the []interface{} to your function. BTW. Don't use interface{}. – Volker Nov 26 '15 at 13:53
  • @Volker why not `interface{}` ? – roger Nov 26 '15 at 13:54
  • @Volker and what is difference between my code and this [mgo insert method](http://bazaar.launchpad.net/+branch/mgo/v2/view/head:/session.go#L1823) – roger Nov 26 '15 at 13:57
  • Remove "..." 3 dots from "this.setItemList(jobColl, jobList...)", it should be this.setItemList(jobColl, jobList), jobList is already an array – Prashant Thakkar Nov 26 '15 at 14:23
  • @PrashantThakkar that is not right, jobList will become just one parameter, such as `[3, 4, 5]`, if without `....`, it becomes `[[3, 4, 5]] ` – roger Nov 26 '15 at 14:25
  • I remember in the past someone had a similar problem with `fmt.Sscan`: http://stackoverflow.com/q/28604563/847869 – tomasz Nov 26 '15 at 15:34
  • This is a quite common golang gotcha. – Ezequiel Moreno Nov 26 '15 at 15:46

2 Answers2

2

I think what you're looking for is this

package main

import "fmt"

func main() {
    interfacetious := []interface{}{"s", 123, float64(999)}
    stuff(interfacetious)
    stuff2(interfacetious...)

    stuff2("or", 123, "separate", float64(99), "values")
}

// Stuff can only work with slice of things
func stuff(s []interface{}) {
    fmt.Println(s)
}

// Stuff2 is polyvaridc and can handle individual vars, or a slice with ...
func stuff2(s ...interface{}) {
    fmt.Println(s)
}
Mike Graf
  • 5,077
  • 4
  • 45
  • 58
2

The question correctly declares the setItemList method, assuming that you want a variadic argument. Because the setList function works with any Mongo document type, it is appropriate to use interface{} in this scenario.

A []*cv_type.CvJobItemRaw cannot be converted to a []interface{}. Write a loop to create the []interface{} from jobList.

jobList := cvRaw.GetJobList()
s := make([]interface{}, len(t))
for i, v := range t {
    s[i] = v
}
this.setItemList(jobColl, s...)

See the Go Language FAQ for more details.