简体   繁体   English

如何使 function 接受任何类型的数组作为 GO 中的参数?

[英]How to make a function accept any type array as param in GO?

I need to create a function that takes any type array as param.我需要创建一个将任何类型数组作为参数的 function。

package main

import "fmt"

type flt func(interface{}) bool

func filter(sl []interface{}, f flt) (filtered []interface{}) {
    // todo call flt to each element on array
    return
}

func f1(interface{}) bool{
    return true
}

func main() {
    slice := []int{1, 2, 3, 4, 5, 7}
    filter(slice, f1)
}
./prog.go:16:8: cannot use slice (type []int) as type []interface {} in argument to filter

I founded this question , but the solution doesn't work with arrays.我创立了这个问题,但该解决方案不适用于 arrays。

edit1.编辑1。 By the way, you probably notice, but I'm trying to create a "map function" to any array, just like JS array.filter()顺便说一句,您可能注意到了,但我正在尝试为任何数组创建一个“映射函数”,就像 JS array.filter()

I was wrong about the use of Interface{}.我对 Interface{} 的使用是错误的。 I don't need to say that it's an array, just a regular Interface{} is able to receive a slice of any type.我不需要说它是一个数组,只是一个常规的 Interface{} 能够接收任何类型的切片。

Just like icza said I used reflection to get the type of Interface{}, but by using "reflect.TypeOf(el).Kind().= reflect. Slice" I avoided the manual type handler and get my general function just like I wanted.就像 icza 说我使用反射来获取 Interface{} 的类型,但是通过使用“reflect.TypeOf(el).Kind().= reflect.Slice”,我避免了手动类型处理程序并像我一样得到我的一般 function通缉。

package main

import (
    "errors"
    "reflect"
)

type flt func(interface{}) bool

func filter(el interface{}, f flt) (filtered interface{}, err error) {
    if reflect.TypeOf(el).Kind() != reflect.Slice {
        err = errors.New("Passed element is not an slice")
        filtered = el
        return
    }
    // todo -> apply flt to each element from array
    return
}

func f1(interface{}) bool {
    return true
}

func main() {
    slice := []int{1, 2, 3, 4, 5, 7}
    slice2 := []string{"1", "2", "a"}
    filter(slice, f1)
    filter(slice2, f1)
    filter(1, f1)
}

check this also: How to check if interface{} is a slice也检查一下: 如何检查 interface{} 是否为切片

You can still use reflect您仍然可以使用反射

package main

import (
    "fmt"
    "reflect"
)

type flt func(interface{}) bool

func filter(sl interface{}, f flt) interface{} {
    v := reflect.ValueOf(sl)
    filtered := reflect.MakeSlice(v.Type(), 0, v.Len()-1)
    for i := 0; i < v.Len(); i++ {
        if f(v.Interface()) {
            filtered = reflect.Append(filtered, v.Index(i))
        }
    }

    return filtered.Interface()
}

func f1(interface{}) bool {
    return true
}

func main() {
    slice := []int{1, 2, 3, 4, 5, 7}
    filtered := filter(slice, f1)
    for _, v := range filtered.([]int) {
        fmt.Printf("Filtered value: %v\n", v)
    }
}

https://go.dev/play/p/hmzgUD8ceb1 https://go.dev/play/p/hmzgUD8ceb1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM