1

I have a Go package that has a large number of (auto-generated) models:

Tax2001_1
Tax2001_2
Tax2001_3
...
Tax2020_1

Each is defined like this:

func NewTax2011_1() *Tax2011_1 {
    return &Tax2011_1 { ... }
}

I want to access them depending on a value (timestamp) that is only known at runtime. So I am trying to put the model constructors into a map:

package tax

type TaxModel interface {
  Calculate()
}

var taxModels = make(map[string]func() *TaxModel)

func init() {
  ...
  taxModels["2011_1"] = NewTax2011_1
  taxModels["2011_2"] = NewTax2011_2
  ...
}

The above code is not correct:

cannot use NewTax2011_1 (type func() *Tax2011_1) as type func() *TaxModel in assignment

Any hint how to achieve that?

2 Answers 2

3

Assuming Tax2011_1 and its friends implement TaxModel interface, you can declare the constructor to return the interface:

func NewTax2011_1() TaxModel {
  return &Tax2011_1{}
}

You should not use an interface pointer:

var taxModels = make(map[string]func() TaxModel)

Then it should work.

If you cannot change the constructors, you can use an adapter function:

func NewTax2011_1() *Tax2011_1 {...}

var taxModels = make(map[string]func() TaxModel)

func init() {
  ...
  taxModels["2011_1"] = func() TaxModel {return NewTax2011_1()}
  taxModels["2011_2"] = func () TaxModel {return NewTax2011_2() }
  ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! That looks like it would work - if I could change the generated packages. What if I can not?
Then use the suggestion in the second part.
1

Here's a test I made which seems to work. Looks like you need to not use a pointer to interface. That is what seems to be the problem.


package main

import "fmt"

type Model_1 struct {
        Name string
}

type Model_2 struct {
        Name string
}

func (m *Model_1) Calculate() int64 {
        return 0
}

func (m *Model_2) Calculate() int64 {
        return 0
}

type Model interface {
        Calculate() int64
}

func main() {
        m := make(map[string]func() Model)
        m["test"] = func() Model {
                return &Model_1{Name: "m"}
        }
        fmt.Println(m["test"]().Calculate())
}

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.