我正在实现任务轮询器(从数据库中恢复未完成的任务)。
任务必须满足定义的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()
方法?
答案 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()