近期学习 go语言,想自己写点什么练习一下。大体需求是这样:就是客户端发送给服务器一个请求,服务器解析收到的数据,然后执行对应的方法。实际上客户端发过来的应该是一个函数名和对应的函数参数,当然了也可以有其他的数据。go自带的rpc我也不知道什么原因只能传递一个参数,一种是gob编码,一种是json编码,参数的解析在解编码的时候完成的。
自己写这个也不是要做什么工程,只是想学习一下。
思路1:自己写一种编码,类似b编码的那种,这样的话参数传递比较自由。因为是练习可能也没考虑需求,可能实际并不需要那么多类型的参数,这个粗略考虑可以满足需求
思路2:方法和参数放在一个结构体里,用json编码后发过来。服务器在注册函数原型的时候可以知道函数参数的个数和具体类型,所以现在遇到的问题就是,解json之后这个结构变成了map[string]interface 每个参数的值现在是interface类型,然后也知道实际需要的类型,但是没有办法拼起来。
funcName := f["func_name"]
mfunc, ok := funcMap[funcName.(string)]
if !ok {
log.Fatal("unkown method")
return ""
}
mArgs := mfunc.ArgType
argrValus := make([]reflect.Value, 0)
argNums := len(mArgs)
for i := 0; i < argNums; i++ {
argkey := "arg" + strconv.Itoa(i+1)
arg, ok := f[argkey]
if !ok {
log.Fatal("function args error")
}
v := reflect.ValueOf(arg)
var tmp reflect.Value
if mArgs[i].Kind() == reflect.Ptr {
tmp = reflect.New(mArgs[i].Elem())
} else {
tmp = reflect.New(mArgs[i])
}
//tmp.Elem().set(?) 这个地方类型不对不能set
}
有大佬有什么办法吗?或者有其他思路。感谢!
第 1 条附言 ·
type methodType struct {
method reflect.Method
ArgType []reflect.Type
RetType reflect.Type
Recver reflect.Value
}
var funcMap map[string]*methodType = map[string]*methodType{}
//这个是传递之前的结构体,到server之后并不知道会有几个arg
var request struct {
FuncName string `json:"func_name"`
Arg1 interface{} `json:"arg1"`
Arg2 interface{} `json:"arg2"`
}
var f interface{}
json.Unmarshal(buf[:n],&f)
原文代码中的f就是json解完之后的f
知道是int可以去.(int),但是现在的函数参数的类型是mArgs[i], 如果去类型断言,基本类型可以.int .string这样转,但是slice,struct.map就没办法知道具体是怎样的slice,怎样的struct
#4
更多评论
# 把json直接解析成结构体encoding/json包
```
package main
import (
"encoding/json"
"fmt"
)
func main() {
var jsonBlob = []byte(`[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`)
type Animal struct {
Name string
Order string
}
var animals []Animal
err := json.Unmarshal(jsonBlob, &animals)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", animals)
}
```
#1