从JSON字符串还原满足定义的接口的结构

时间:2018-06-30 19:05:44

标签: go reflection

我正在实现任务轮询器(从数据库中恢复未完成的任务)。

任务必须满足定义的Task接口:

type Task interface {
    // Identifier returns a unique string of a task
    Identifier() string
    // Data should be persistent
    Data() interface{}
    // Execute a task
    Execute()
}

数据库中存储的数据满足以下结构:

type Record struct {
    Identifier string      `json:"identifier"`
    Data       interface{} `json:"data"`
}

任务轮询器启动时,它从数据库中读取存储的数据,然后(让我们暂时忽略错误处理):

r := &Record{}
result := database.Get(key)
json.Unmarshal([]byte(result), r)

我们将保存的数据从数据库恢复到r

出现一个问题,我无法调用Execute()方法,因为r.Data实际上是interface{}类型之外的map[string]interface{}类型(更具体地说是Task

如何将r.Data转换或转换为满足Task接口的结构,以便我可以成功调用Execute()方法?

1 个答案:

答案 0 :(得分:1)

  

r.Data实际上是interface{}map[string]interface{}   更具体地说)。

您需要一个满足Task接口的方法集。例如,

package main

import "fmt"

type Task interface {
    // Identifier returns a unique string of a task
    Identifier() string
    // Data should be persistent
    Data() interface{}
    // Execute a task
    Execute()
}

type Record struct {
    Identifier string      `json:"identifier"`
    Data       interface{} `json:"data"`
}

type Data map[string]interface{}

// Task interface methods
func (d Data) Identifier() string { return "" }
func (d Data) Data() interface{}  { return nil }
func (d Data) Execute()           { fmt.Println("Execute()") }

func main() {
    r := Record{Data: map[string]interface{}{}}
    fmt.Printf("r.Data: %[1]T %[1]v\n", r.Data)
    if m, ok := r.Data.(map[string]interface{}); ok {
        r.Data = Data(m)
    }

    var tasks []Task
    if task, ok := r.Data.(Task); ok {
        tasks = append(tasks, task)
    }

    for _, task := range tasks {
        fmt.Printf("%T: ", task)
        task.Execute()
    }
}

游乐场:https://play.golang.org/p/SC9Ff8e-_pP

输出:

r.Data: map[string]interface {} map[]
main.Data: Execute()