Reputation: 4851
I am trying to create a slice from a reflect.Type
. This is what I have so far.
package main
import (
"fmt"
"reflect"
)
type TestStruct struct {
TestStr string
}
func main() {
elemType := reflect.TypeOf(TestStruct{})
elemSlice := reflect.New(reflect.SliceOf(elemType)).Interface()
elemSlice = append(elemSlice, TestStruct{"Testing"})
fmt.Printf("%+v\n", elemSlice)
}
However I get the following error and I'm not sure how to get around it without hardcoding a conversion to []TestStruct
.
prog.go:17: first argument to append must be slice; have interface {}
Is there anyway to treat the returned interface as a slice without having to hardcode the conversion from interface{}
to []TestStruct
?
Upvotes: 6
Views: 10497
Reputation:
No, what you describe is not possible. Not type asserting the result of .Interface()
limits what you can do. Your best chance is to continue to work with the reflect.Value
value:
package main
import (
"fmt"
"reflect"
)
type TestStruct struct {
TestStr string
}
func main() {
elemType := reflect.TypeOf(TestStruct{})
elemSlice := reflect.MakeSlice(reflect.SliceOf(elemType), 0, 10)
elemSlice = reflect.Append(elemSlice, reflect.ValueOf(TestStruct{"Testing"}))
fmt.Printf("%+v\n", elemSlice)
}
https://play.golang.org/p/WkGPjv0m_P
Upvotes: 16
Reputation:
1- Using reflect.MakeSlice(reflect.SliceOf(elemType), 0, 10)
and
reflect.Append(elemSlice, reflect.ValueOf(TestStruct{"Testing"}))
,
Like this working sample code:
package main
import "fmt"
import "reflect"
func main() {
elemType := reflect.TypeOf(TestStruct{})
elemSlice := reflect.MakeSlice(reflect.SliceOf(elemType), 0, 10)
elemSlice = reflect.Append(elemSlice, reflect.ValueOf(TestStruct{"Testing"}))
fmt.Println(elemSlice) // [{Testing}]
}
type TestStruct struct {
TestStr string
}
2- Using reflect.New(reflect.SliceOf(elemType)).Elem()
and
elemSlice = reflect.Append(elemSlice, reflect.ValueOf(TestStruct{"Testing"}))
Like this working sample code:
package main
import "fmt"
import "reflect"
type TestStruct struct {
TestStr string
}
func main() {
elemType := reflect.TypeOf(TestStruct{})
elemSlice := reflect.New(reflect.SliceOf(elemType)).Elem()
elemSlice = reflect.Append(elemSlice, reflect.ValueOf(TestStruct{"Testing"}))
fmt.Printf("%+v\n", elemSlice) // [{TestStr:Testing}]
fmt.Println(elemSlice) // [{Testing}]
}
Output:
[{TestStr:Testing}]
[{Testing}]
3- If you need append
, the only way is using s := elemSlice.([]TestStruct)
, like this working sample code:
package main
import "fmt"
import "reflect"
type TestStruct struct {
TestStr string
}
func main() {
elemType := reflect.TypeOf(TestStruct{})
elemSlice := reflect.New(reflect.SliceOf(elemType)).Elem().Interface()
s := elemSlice.([]TestStruct)
s = append(s, TestStruct{"Testing"})
fmt.Printf("%+v\n", elemSlice) // []
fmt.Println(s) // [{Testing}]
}
Upvotes: 6