Go 如何确定切片接口{}的元素类型?
我有以下代码来加倍切片Go 如何确定切片接口{}的元素类型?,go,Go,我有以下代码来加倍切片 func doubleSlice(s []int) []int { t := make([]int, len(s), (cap(s) + 1) * 2 ) for i := range s { t[i] = s[i] } return t } 我想让func将任何类型的切片加倍。我需要先知道元素类型 func showInterfaceItem(s interface{}) interface{} { if reflect.TypeOf(s
func doubleSlice(s []int) []int {
t := make([]int, len(s), (cap(s) + 1) * 2 )
for i := range s {
t[i] = s[i]
}
return t
}
我想让func将任何类型的切片加倍。我需要先知道元素类型
func showInterfaceItem(s interface{}) interface{} {
if reflect.TypeOf(s).Kind() != reflect.Slice {
fmt.Println("The interface is not a slice.")
return
}
var t interface{}
newLen := reflect.ValueOf(s).Len()
newCap := (cap(reflect.ValueOf(s).Cap()) + 1) * 2
t = make([]reflect.TypeOf(s), newLen, newCap)
return t
}
reflect.TypeOf(s)
返回接口{}的类型,而不是元素的类型。如何获取切片接口的元素类型?您可以使用reflect.TypeOf(s.Elem()
获取切片元素的类型
package main
import (
"fmt"
"reflect"
)
func doubleSlice(s interface{}) interface{} {
if reflect.TypeOf(s).Kind() != reflect.Slice {
fmt.Println("The interface is not a slice.")
return nil
}
v := reflect.ValueOf(s)
newLen := v.Len()
newCap := (v.Cap() + 1) * 2
typ := reflect.TypeOf(s).Elem()
t := reflect.MakeSlice(reflect.SliceOf(typ), newLen, newCap)
reflect.Copy(t, v)
return t.Interface()
}
func main() {
xs := doubleSlice([]string{"foo", "bar"}).([]string)
fmt.Println("data =", xs, "len =", len(xs), "cap =", cap(xs))
ys := doubleSlice([]int{3, 1, 4}).([]int)
fmt.Println("data =", ys, "len =", len(ys), "cap =", cap(ys))
}
输出将是:
data = [foo bar] len = 2 cap = 6
data = [3 1 4] len = 3 cap = 8
登记:这在golang是可行的,我花了一整天的时间来发现模式 首先,我们想得到一个slice指针,使gorm高兴,它的类型是“*[]Obj”。为了在golang实现这一点,我们可以创建一个make包装器,如下所示:
func makeWrapper(cap-uint)接口{{
arr:=制造([]某物,0,上限)
返回和arr
}
注意,我们不能直接引用maked值,这可能是簿记数据需要有一个堆栈空间来存储
//不起作用的示例
func makeWrapper(cap uint)接口{}{
返回和(制作([]某物,0,上限))
}
正如前面的答案一样,reflect.MakeSlice(reflect.SliceOf(typ),0,capacity).Interface()
返回Interface{[]Sth}
。(这里的typ
是指reflect.TypeOf(Sth{})
,相当于typ==reflect.TypeOf(v)
)
因此,我们需要创建一个返回对象*[]Sth
,其中的值是一个具有容量的切片[]Sth
。理解目标后,我们可以得到以下代码:
主程序包
进口(
“反映”
)
键入某个结构{
a、 b弦
}
func main(){
af:=createSlice(Sth{})
arr:=makeWrapper(10)
println(reflect.TypeOf(arr.String())
//相当于makeWrapper,但我们通过反射来实现
arr=af(10)。(*[]某物)
println(reflect.TypeOf(arr.String())
}
func makeWrapper(cap uint)接口{}{
arr:=制造([]某物,0,上限)
返回和arr
}
func createSlice(v接口{})func(int)接口{}{
变量类型反射类型
如果reflect.ValueOf(v).Kind()=reflect.Ptr{
typ=reflect.ValueOf(v).Elem().Type()
}如果reflect.ValueOf(v.Kind()==reflect.Struct,则为else{
类型=反射。类型(v)
}否则{
恐慌(“仅支持结构的实例或该实例的指针”)
}
返回func(容量int)接口{}{
//创建外部对象保存切片
outerObj:=reflect.New(reflect.SliceOf(典型))
//创建切片并保存以返回
outerObj.Elem().Set(reflect.MakeSlice(reflect.SliceOf(典型),0,容量))
//检索外部对象的接口
返回outerObj.Interface()
}
}
不完全清楚您尝试了什么?在没有返回变量的函数中返回值func showInterfaceItem(s interface{})({{somethine here}}}{/code>我想实现自动检查元素类型。如果s
是[]int
,t
是[]int
,如果s
是[]float32
,t
是[/code>]float32
。我想你误解了我的问题…你的函数不会编译。如果你返回一个值return t
,但是你的函数没有返回值reflect.MakeSlice()
和reflect.Sliceof()
就是我需要的。有了它们,我实现了我的计划。