Reputation: 924
I want to initialize a map containing a list of interface without having to add them one by one:
type Pixel struct {
X float64
Y float64
}
type Vertex struct {
X float64
Y float64
Z float64
}
type testpair struct {
filename string
values []interface{}
}
var tests = map[string]testpair{
"test1": {
filename: "file1.csv",
values: []Pixel{
{X: 12.5, Y: 23.4},
{X: 17.2, Y: 7.9},
}
},
"test2": {
filename: "file2.csv",
values: []Vertex{
{X: 10.7, Y: 13.3, Z: 25.1},
{X: 18.3, Y: 16.9, Z: 16.4},
}
},
}
The compiler would output such an error:
cannot use []Pixel literal (type []Pixel) as type []interface {} in field value
If I switch []interface{} to []Pixel, I can initialize the map but I can do it only with a unique type Pixel or Vertex.
Is there a way to force the compiler to accept array initialization with a specific struct while declaring it as an array of interface?
Upvotes: 9
Views: 21387
Reputation: 3543
I had the same problem but was about to use primitives so this suggested solution here want work. In that case I helped my self out with:
args := make([]interface{}, 2)
args[0] = "some string"
args[1] = 1 //some int
Upvotes: 1
Reputation: 9
To be able to initialize you need to input a type to the interface and not an array of type, so suggest you to change as follow:
type Pixel struct {
X float64
Y float64
}
type Pixels []Pixel
type Vertex struct {
X float64
Y float64
Z float64
}
type Vertexs []Vertex
type testpair struct {
filename string
values interface{}
}
var tests = map[string]testpair{
"test1": {
filename: "file1.csv",
values: Pixels{
Pixel{X: 12.5, Y: 23.4},
Pixel{X: 17.2, Y: 7.9}}},
"test2": {
filename: "file2.csv",
values: Vertexs{
Vertex{X: 10.7, Y: 13.3, Z: 25.1},
Vertex{X: 18.3, Y: 16.9, Z: 16.4}}}}
Upvotes: 0
Reputation: 34292
If you have to create a slice of values for passing to something that requires a slice of interface{}
(which, depending on the context, may or may not be appropriate design) or a slice of any more specific interface, you have to specify each element fully, like this:
[]interface{}{
Pixel{X: 12.5, Y: 23.4},
Pixel{X: 17.2, Y: 7.9},
}
That also means that you can pass things like:
[]interface{}{
Pixel{X: 12.5, Y: 23.4},
Vertex{X: 10.7, Y: 13.3, Z: 25.1},
}
which is hardly something you intended, and compiler won't warn you. I don't see that a big deal for the testing code, though.
Upvotes: 18
Reputation: 42431
Is there a way to force the compiler to accept array initialization with a specific struct while declaring it as an array of interface?
No. Basically you cannot force the Go compiler to anything.
See also the FAQ: https://golang.org/doc/faq#convert_slice_of_interface
You must supply a []interface{}
.
But please stop doing this and come up with something not requiring the empty interface.
Upvotes: 3