1

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

2
  • Did you try (items ...)? Commented May 9, 2016 at 11:14
  • compiler says final argument in variadic function missing type Commented May 9, 2016 at 11:16

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

sorry, my bad forgot important details why i can't use Items type in declaration added to question
0

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

4 Comments

sorry, my bad forgot important details why i can't use Items type in declaration added to question
This is syntactically incorrect: undefined: report in report.Items. Also, if you wanted to use a variadic function you would need to call doSmth like doSmth(report.Items...).
report variable created earlier kind of report := getReport()
Actually this error comes from the function definition not where the function is called: play.golang.org/p/rELz-hXgGC.
0

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) {
  ...
}

Comments

0

You can call like this type of array of struct values using basic array concepts : In this example , []item should be called as item.Item[i].Unitprice

I hope u would got some idea


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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.