[英]Cast an interface using a pointer of a Slice to iterate its values
Using a custom Binder and Validator in Echo Framework.在 Echo 框架中使用自定义的 Binder 和 Validator。 The binder use a signature of (interface{}, echo.Context)
, but a pointer is always passed and checked by echo.DefaultBinder
.活页夹使用(interface{}, echo.Context)
的签名,但指针始终由echo.DefaultBinder
传递和检查。
I'm having trouble validating an array of struct for some reason, when an array is passed for some unknown reason.当由于某种未知原因传递数组时,由于某种原因,我无法验证结构数组。 Therefore, I'm trying to validate each elements in the interface, if this interface is an Array or a Slice.因此,我正在尝试验证接口中的每个元素,如果此接口是数组或切片。
I cannot find a way to both cast the interface
to a value
instead of a pointer
and iterate trough the values of this array to validate each of them.我找不到一种方法既可以将interface
转换为value
而不是pointer
,又可以遍历该数组的值以验证它们中的每一个。
My Code so far:到目前为止我的代码:
func (cb *CustomBinder) Bind(i interface{}, c echo.Context) error {
db := new(echo.DefaultBinder)
validate := validator.New()
if err := db.Bind(i, c); err != nil {
return err
}
kind := reflect.ValueOf(i).Elem().Kind()
if kind == reflect.Array || kind == reflect.Slice {
// ... Iteration and Validation
} else {
if err := validate.Struct(i); err != nil {
return err
}
}
return nil
}
I would rather use type assertions than reflection because reflection is slow in terms of performance and not friendly to use.我宁愿使用类型断言而不是反射,因为反射在性能方面很慢并且使用起来不友好。
To illustrate what I mean, check this example code where I have a function that accepts an argument of type interface{}
and prints the values according to the data type,为了说明我的意思,请查看此示例代码,其中我有一个 function 接受interface{}
类型的参数并根据数据类型打印值,
package main
import (
"fmt"
)
func main() {
var dynamicValue interface{}
dynamicValue = []interface{}{"value1", "value2"}
printValue(dynamicValue)
dynamicValue = map[string]interface{}{"key1": "value1"}
printValue(dynamicValue)
dynamicValue = "value1"
printValue(dynamicValue)
}
func printValue(i interface{}) {
if arrayValue, isArray := i.([]interface{}); isArray {
for index, value := range arrayValue {
fmt.Printf("Index: %d Value: %v \n", index, value)
}
} else if mapValue, isMap := i.(map[string]interface{}); isMap {
for key, value := range mapValue {
fmt.Printf("Key: %s Value: %v \n", key, value)
}
} else if stringValue, isString := i.(string); isString {
fmt.Println(stringValue)
} else {
fmt.Println("Invalid data type! Only supports string, arrays and maps ")
}
}
Output: Output:
Index: 0 Value: value1索引:0 值:value1
Index: 1 Value: value2索引:1 值:值2
Key: key1 Value: value1键:key1 值:value1
value1价值1
Playground: https://play.golang.org/p/TMfojVdoi5b游乐场: https://play.golang.org/p/TMfojVdoi5b
You can use this logic of type assertion in your code to check if the interface
is a slice and iterate over it for validation.您可以在代码中使用这种类型断言逻辑来检查interface
是否为切片并对其进行迭代以进行验证。
Something like this,像这样的东西,
func (cb *CustomBinder) Bind(i interface{}, c echo.Context) error {
db := new(echo.DefaultBinder)
validate := validator.New()
if err := db.Bind(i, c); err != nil {
return err
}
if arrayValue, isArray := i.([]interface{}); isArray {
// Iteration
for index, value := range arrayValue {
// Validation
}
} else {
if err := validate.Struct(i); err != nil {
return err
}
}
return nil
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.