I am trying to re-use code (Key/Value) pair to build ec2.Tag and autoscaling.Tag types, which are also Key/Value pairs. But I don't think I know enough about conversion/casting, please advise. Thank you in advance.
panic: interface conversion: interface {} is []struct { Key string; Value string }, not []*ec2.Tag
func (c *CloudWorks) GetTagCollection() interface{} {
return []struct {
Key string
Value string
}{
{
Key: "key-a",
Value: "value-a",
},
{
Key: "key-b",
Value: "value-b",
},
{
Key: "key-c",
Value: "value-c",
},
}
}
func (c *CloudWorks) GetTags() []*ec2.Tag {
//return []*autoscaling.Tag{
// WORKS
//return []*ec2.Tag{
// {
// Key: aws.String("key1"),
// Value: aws.String("value1"),
// },
// {
// Key: aws.String("key2"),
// Value: aws.String("value3"),
// },
// {
// Key: aws.String("key3"),
// Value: aws.String("value3"),
// },
//}
// FAIL
return c.GetTagCollection().([]*ec2.Tag)
}
EDIT my objective is to avoid code duplicity, how can I re-use key-value pairs amongst both functions, thanks so much.
func (c *CloudWorks) GetEC2Tags() []*ec2.Tag {
return []*ec2.Tag{
{
Key: aws.String("key1"),
Value: aws.String("value1"),
},
{
Key: aws.String("key2"),
Value: aws.String("value3"),
},
}
}
func (c *CloudWorks) GetAutoscalingTags() []*autoscaling.Tag {
return []*autoscaling.Tag{
{
Key: aws.String("key1"),
Value: aws.String("value1"),
},
{
Key: aws.String("key2"),
Value: aws.String("value3"),
},
}
}
The term you are using is not conversion/casting
, it is type assertion which is used to get the underlying value of an interface. Since the interface that you are using to wrap the content of the function when returning the data is a slice of struct. That's the reason behind the error:
panic: interface conversion: interface{} is []struct { Key string; Value string }, not []*ec2.Tag
Type assertion is wrong, because you are using []*ec2.Tag
ad type, which should be slice of struct []struct
returned from the function c.GetTagCollection()
. So you should type assert to that type as:
result := c.GetTagCollection().([]struct)
A type assertion used in an assignment or initialization of the special form so you check if type asssertion works:
v, ok = x.(T)
v, ok := x.(T)
For an expression x of interface type and a type T, the primary expression
x.(T)
asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion.
More precisely, if T is not an interface type, x.(T) asserts that the dynamic type of x is identical to the type T. In this case, T must implement the (interface) type of x; otherwise the type assertion is invalid since it is not possible for x to store a value of type T. If T is an interface type, x.(T) asserts that the dynamic type of x implements the interface T.
Note: If the type assertion holds, the value of the expression is the value stored in x and its type is T. If the type assertion is false, a run-time panic occurs.
Edit: Golang is strict about types. So you cannot assign value of one type to other type until you convert the value to another type. AWS creates it own types using the provided string. Take for an example:
package main
import (
"fmt"
)
type MyInt int
func main() {
var x int
x = 1
var y MyInt
y = 1
fmt.Println(x==y)
}
Above code will throw an error of mismatch types
prog.go:14:18: invalid operation: x == y (mismatched types int and MyInt)
Working Code on Playground