rencalo770 / gengine

Rule Engine for Golang
Other
433 stars 70 forks source link

发现一个加法类型错误的问题 #22

Open wiz558 opened 2 years ago

wiz558 commented 2 years ago

您好!

首先非常感觉您提供一个很好的开源项目。我在使用时遇到这个的问题,我感觉是一个Bug但不确定。

以下是我的测试脚本:

rule "test01" "test" begin a =1.0 x=0.0 b = req.GetArgs(@name,0) x = a + b + 2000 end

参数InArgs是在初始化req结构时定义好的,通过注入的req结构方法来获得每个规则执行时的输入参数。

//Request . 规则请求结构 type Request struct { //当前账户系统信息 pubstruct.AccountInfo // 规则执行设置 [规则名][参数1~n] InArgs map[string][]interface{} }

func (me *Request) GetArgs(ruleName string, idx int) interface{} { if v, ok := me.InArgs[ruleName]; ok { return v[idx] } return nil }

规则在执行到math.go 第49行时报错,程序终止,原因是因为req.GetArgs 返回的是一个interface{} 【实际是float64】

if strings.HasPrefix(bkind, "int") { // 这里会放行所有int,interface也会放行 我在测试时 bkind刚好是interface return a.Float() + float64(b.Int()), nil //math.go:49 }

我已修正了GetArgs的返回类型,目前运行正常。以上报告供您参考。

再次感谢

浙江嘉兴 老李

wiz558 commented 2 years ago

我尝试将core/math.go 作些改动,能解决问题。请作者斧正。

//add 211130 // 查找interface嵌套 一直找到不是interface的值 func GetValue(typ string, v reflect.Value) (rtyp string, rv reflect.Value) { rtyp = reflect.ValueOf(v.Interface()).Kind().String() rv = reflect.ValueOf(v.Interface()) if rtyp == interface { return GetValue(rtyp, rv) } return } //end func Add(a, b reflect.Value) (interface{}, error) { akind := a.Kind().String() bkind := b.Kind().String() //add begin if akind == interface { akind, a = GetValue(akind, a) } if bkind == interface { akind, b = GetValue(bkind, b) } //add..end if akind == "string" && bkind == "string" { //字符串相加 return fmt.Sprintf("%s%s", a.String(), b.String()), nil }

if strings.HasPrefix(akind, "int") {
    if strings.HasPrefix(bkind, "int") {
        return a.Int() + b.Int(), nil
    }

    if strings.HasPrefix(bkind, "uint") {
        return a.Int() + int64(b.Uint()), nil
    }

    if strings.HasPrefix(bkind, "float") {
        return float64(a.Int()) + b.Float(), nil
    }
}