Golang中如何读取接口内的Map数据

Golang中如何读取接口内的Map数据 你好,

我使用了一个包来反序列化PHP序列化数据,它返回一个包含内部映射的接口。我该如何读取该接口中的映射?

使用的包是:github.com/wulijun/go-php-serialize/phpserialize

获取反序列化数据后,结果如下:

map[type:feedexport/rule_condition_combine attribute:<nil> operator:<nil> value:1 
is_value_processed:<nil> aggregator:any 
conditions:map[0:map[type:feedexport/rule_condition_product attribute:sku operator:== 
value:AMW-1900-50SLE-ROOM is_value_processed:false] 1:map[attribute:sku operator:== 
value:ASL-B654-77-74-98-ROOM is_value_processed:false 
type:feedexport/rule_condition_product] 2:map[value:ASL-B217-57-54S-95-ROOM 
is_value_processed:false type:feedexport/rule_condition_product attribute:sku operator:==]]]

请问有人能帮助我吗?


更多关于Golang中如何读取接口内的Map数据的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

这段代码片段是针对我提出的解决方案的后续问题吗?

如果是这样,很抱歉,我不明白你想通过这个问题表达什么。如果不是,我仍然没有理解你的意思。

更多关于Golang中如何读取接口内的Map数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你需要进行类型断言类型切换来确保类型正确,然后就可以正常处理了。

PS:根据我的记忆,它会是一个 map[interface{}]interface{},在访问映射时需要重新对键和值进行类型转换和断言。当我不得不使用该库时,代码因此变得非常混乱。如果你能说服数据源改用JSON格式输出,事情可能会简单得多!

package main

import (
    "fmt"
    "github.com/wulijun/go-php-serialize/phpserialize"
)

func main() {
    rules := RulesList()

    for key := range rules {
        fmt.Println(rules[key])
    }
}

type Rule struct {
    RuleId      int         `json:"rule_id"`
    Conditions interface{} `json:"conditions"`
}

func RulesList() ([]Rule) {
    db := DbConn()
    res, err := db.Query(`SELECT r.rule_id, r.conditions_serialized AS conditions FROM 
        m_feedexport_rule AS r`)
    CheckError(err)

    rule  := Rule{}
    rules := []Rule{}
    for res.Next()  {
        var ruleId int
        var conditions string
        err = res.Scan(&ruleId, &conditions)
        CheckError(err)

        conditionsInterface := make(map[interface{}]interface{})
        var condition []interface{}

        cons, err := phpserialize.Decode(conditions)
        CheckError(err)
        conditionsInterface[ruleId] = cons

        condition = append(condition, conditionsInterface)

        rule.RuleId     = ruleId
        rule.Conditions = condition

        rules = append(rules, rule)
    }

    return rules
}

这是我想执行的代码。

在Golang中读取接口内的Map数据,需要使用类型断言将接口转换为具体的map类型。根据你提供的反序列化结果,这是一个嵌套的map结构,键为字符串,值为接口类型。

以下是读取该接口中映射数据的示例代码:

package main

import (
    "fmt"
    "github.com/wulijun/go-php-serialize/phpserialize"
)

func main() {
    // 假设这是你的反序列化结果
    var data interface{}
    
    // 首先进行类型断言,将接口转换为map[string]interface{}
    if result, ok := data.(map[string]interface{}); ok {
        // 读取顶层的map数据
        fmt.Println("Type:", result["type"])
        fmt.Println("Aggregator:", result["aggregator"])
        fmt.Println("Value:", result["value"])
        
        // 读取conditions中的嵌套map
        if conditions, ok := result["conditions"].(map[string]interface{}); ok {
            // 遍历conditions中的每个条件
            for key, condition := range conditions {
                fmt.Printf("Condition %s:\n", key)
                
                // 将每个条件断言为map[string]interface{}
                if condMap, ok := condition.(map[string]interface{}); ok {
                    fmt.Printf("  Type: %v\n", condMap["type"])
                    fmt.Printf("  Attribute: %v\n", condMap["attribute"])
                    fmt.Printf("  Operator: %v\n", condMap["operator"])
                    fmt.Printf("  Value: %v\n", condMap["value"])
                    fmt.Printf("  Is Value Processed: %v\n", condMap["is_value_processed"])
                }
            }
        }
    }
}

如果需要处理更复杂的嵌套结构,可以使用递归函数:

func printMap(data map[string]interface{}, indent string) {
    for key, value := range data {
        switch v := value.(type) {
        case map[string]interface{}:
            fmt.Printf("%s%s:\n", indent, key)
            printMap(v, indent+"  ")
        case []interface{}:
            fmt.Printf("%s%s: [array]\n", indent, key)
        default:
            fmt.Printf("%s%s: %v\n", indent, key, v)
        }
    }
}

// 使用方式
if result, ok := data.(map[string]interface{}); ok {
    printMap(result, "")
}

对于你特定的数据结构,可以直接访问特定字段:

// 直接访问特定字段的示例
if result, ok := data.(map[string]interface{}); ok {
    // 获取第一个条件
    if conditions, ok := result["conditions"].(map[string]interface{}); ok {
        if cond0, ok := conditions["0"].(map[string]interface{}); ok {
            fmt.Println("First condition SKU:", cond0["value"])
        }
    }
}

关键是要使用类型断言将接口转换为具体的map类型,然后就可以像普通map一样访问其中的数据了。

回到顶部