英文:
How to create a slice of variable type in Go?
问题
我有一个函数。
func doSome(v interface{}) {
}
如果我通过指针将一个结构体切片传递给函数,函数必须填充该切片。
type Color struct {
}
type Brush struct {
}
var c []Color
doSome(&c) // 在执行后,c将包含3个Color类型的元素的数组
var b []Brush
doSome(&b) // 在执行后,b将包含3个Brush类型的元素的数组
也许我需要使用反射,但是如何使用呢?
英文:
I have a function.
func doSome(v interface{}) {
}
If I pass by pointer a slice of struct into the function, the function must fill the slice.
type Color struct {
}
type Brush struct {
}
var c []Color
doSome(&c) // after с is array contains 3 elements type Color
var b []Brush
doSome(&b) // after b is array contains 3 elements type Brush
Maybe I need use reflection, but how?
答案1
得分: 4
func doSome(v interface{}) {
s := reflect.TypeOf(v).Elem()
slice := reflect.MakeSlice(s, 3, 3)
reflect.ValueOf(v).Elem().Set(slice)
}
将上述代码翻译为中文如下:
func doSome(v interface{}) {
s := reflect.TypeOf(v).Elem()
slice := reflect.MakeSlice(s, 3, 3)
reflect.ValueOf(v).Elem().Set(slice)
}
将上述代码翻译为中文如下:
func doSome(v interface{}) {
s := reflect.TypeOf(v).Elem()
slice := reflect.MakeSlice(s, 3, 3)
reflect.ValueOf(v).Elem().Set(slice)
}
英文:
func doSome(v interface{}) {
s := reflect.TypeOf(v).Elem()
slice := reflect.MakeSlice(s, 3, 3)
reflect.ValueOf(v).Elem().Set(slice)
}
答案2
得分: 3
typeswitch!!
package main
import "fmt"
func doSome(v interface{}) {
switch v := v.(type) {
case *[]Color:
*v = []Color{Color{0}, Color{128}, Color{255}}
case *[]Brush:
*v = []Brush{Brush{true}, Brush{true}, Brush{false}}
default:
panic("unsupported doSome input")
}
}
type Color struct {
r uint8
}
type Brush struct {
round bool
}
func main(){
var c []Color
doSome(&c) // after c is array contains 3 elements type Color
var b []Brush
doSome(&b) // after b is array contains 3 elements type Brush
fmt.Println(b)
fmt.Println(c)
}
类型切换!!
package main
import "fmt"
func doSome(v interface{}) {
switch v := v.(type) {
case *[]Color:
*v = []Color{Color{0}, Color{128}, Color{255}}
case *[]Brush:
*v = []Brush{Brush{true}, Brush{true}, Brush{false}}
default:
panic("不支持的 doSome 输入")
}
}
type Color struct {
r uint8
}
type Brush struct {
round bool
}
func main(){
var c []Color
doSome(&c) // c 现在是包含 3 个 Color 类型元素的数组
var b []Brush
doSome(&b) // b 现在是包含 3 个 Brush 类型元素的数组
fmt.Println(b)
fmt.Println(c)
}
这是一个Go语言的代码示例,它展示了类型切换的用法。在函数doSome
中,根据传入参数的类型进行不同的操作。如果传入的是*[]Color
类型的指针,则将其指向的数组修改为包含三个Color
类型的元素;如果传入的是*[]Brush
类型的指针,则将其指向的数组修改为包含三个Brush
类型的元素。如果传入的类型不是以上两种类型,则会抛出一个错误。
在main
函数中,首先定义了两个空数组c
和b
,然后分别调用doSome
函数对它们进行处理。最后,打印出数组b
和c
的内容。
希望对你有帮助!如果有任何其他问题,请随时问我。
英文:
typeswitch!!
package main
import "fmt"
func doSome(v interface{}) {
switch v := v.(type) {
case *[]Color:
*v = []Color{Color{0}, Color{128}, Color{255}}
case *[]Brush:
*v = []Brush{Brush{true}, Brush{true}, Brush{false}}
default:
panic("unsupported doSome input")
}
}
type Color struct {
r uint8
}
type Brush struct {
round bool
}
func main(){
var c []Color
doSome(&c) // after с is array contains 3 elements type Color
var b []Brush
doSome(&b) // after b is array contains 3 elements type Brush
fmt.Println(b)
fmt.Println(c)
}
答案3
得分: 1
Go语言没有泛型。你有以下几种选择:
- 接口分派
type CanTraverse interface {
Get(int) interface{}
Len() int
}
type Colours []Colour
func (c Colours) Get(i int) interface{} {
return c[i]
}
func (c Colours) Len() int {
return len(c)
}
func doSome(v CanTraverse) {
for i := 0; i < v.Len(); i++ {
fmt.Println(v.Get(i))
}
}
- 类型切换(如@Plato所建议)
func doSome(v interface{}) {
switch v := v.(type) {
case *[]Colour:
// 处理颜色
case *[]Brush:
// 处理画笔
default:
panic("不支持的doSome输入")
}
}
- 反射(类似于fmt.Println()的方式)。反射非常强大,但也非常耗费资源,可能会导致代码运行缓慢。以下是一个简单的示例:
func doSome(v interface{}) {
value := reflect.ValueOf(v)
if value.Kind() == reflect.Slice {
for i := 0; i < value.Len(); i++ {
element := value.Slice(i, i+1)
fmt.Println(element)
}
} else {
fmt.Println("这不是一个切片")
}
}
英文:
Go has no generics. Your possibilities are:
Interface dispatching
type CanTraverse interface {
Get(int) interface{}
Len() int
}
type Colours []Colour
func (c Colours) Get(i int) interface{} {
return c[i]
}
func (c Colours) Len() int {
return len(c)
}
func doSome(v CanTraverse) {
for i := 0; i < v.Len; i++ {
fmt.Println(v.Get(i))
}
}
Type switch as @Plato suggested
func doSome(v interface{}) {
switch v := v.(type) {
case *[]Colour:
//Do something with colours
case *[]Brush:
//Do something with brushes
default:
panic("unsupported doSome input")
}
}
Reflection as fmt.Println() do. Reflection is very powerful but very expensive, code may be slow. Minimal example
func doSome(v interface{}) {
value := reflect.ValueOf(v)
if value.Kind() == reflect.Slice {
for i := 0; i < value.Len(); i++ {
element := value.Slice(i, i+1)
fmt.Println(element)
}
} else {
fmt.Println("It's not a slice")
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论