簡體   English   中英

使用 Slice 的指針轉換接口以迭代其值

[英]Cast an interface using a pointer of a Slice to iterate its values

語境:

在 Echo 框架中使用自定義的 Binder 和 Validator。 活頁夾使用(interface{}, echo.Context)的簽名,但指針始終由echo.DefaultBinder傳遞和檢查。

當由於某種未知原因傳遞數組時,由於某種原因,我無法驗證結構數組。 因此,我正在嘗試驗證接口中的每個元素,如果此接口是數組或切片。

問題:

我找不到一種方法既可以將interface轉換為value而不是pointer ,又可以遍歷該數組的值以驗證它們中的每一個。

到目前為止我的代碼:

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
}

我寧願使用類型斷言而不是反射,因為反射在性能方面很慢並且使用起來不友好。
為了說明我的意思,請查看此示例代碼,其中我有一個 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:
索引:0 值:value1
索引:1 值:值2
鍵:key1 值:value1
價值1

游樂場: https://play.golang.org/p/TMfojVdoi5b

您可以在代碼中使用這種類型斷言邏輯來檢查interface是否為切片並對其進行迭代以進行驗證。
像這樣的東西,

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM