// 人工识别 func TestFunc(T *testing.T) { for _, k := range Funs { if proto.Type(k) != reflect.TypeOf(k).String() { fmt.Println(proto.Type(k), "\t\t", reflect.TypeOf(k).String()) } } fmt.Println(proto.Type(struct { ddd proto.ProtoType A string a string B int }{}), "\t\t", struct{ A string }{A: "struct"}) }
// 人工识别 func TestBuiltin(T *testing.T) { for _, k := range Builtins { s := proto.Type(k) if k != nil && s != reflect.TypeOf(k).String() { fmt.Println(s, "\t\t", reflect.TypeOf(k)) } } }
func (p *Group) register(name string, fn interface{}) { args, outs := proto.FuncSplit(fn) if len(outs) > 2 { outs = outs[1 : len(outs)-1] } args = args[1 : len(args)-1] fun := "func" if name != "" { fun += " " + name } fun += "(" + strings.Join(args, ", ") + ")" key := fun numout := len(outs) ify := "" if numout > 0 && (outs[numout-1] == "bool" || outs[numout-1] == "error") { numout-- ify = outs[numout] } if numout == 1 { key += " " + outs[0] } else if numout > 1 { key += " (" + strings.Join(outs[:numout], ", ") + ")" } // 不允许注册相同 proto 的函数 _, ok := p.m[key] if ok { panic("auto repeated: " + proto.Type(fn)) } n := Fn{name: name} n.args = args n.outs = outs n.apply = reflect.ValueOf(fn) n.ify = ify n.numout = numout p.m[key] = &n p.All = append(p.All, key) }
// 根据参数匹配,或者生成执行函数 func (p *Group) match(kind interface{}, arguments []interface{}) *Fn { to := proto.Type(kind) args := proto.Types(arguments...) // 快速匹配 key := "func(" + strings.Join(args, ", ") + ") " + to fn, ok := p.m[key] if ok { return fn } // 无解 if p.inCloseSet(key) { return nil } // 尝试生成新的序列 np := p.fork() keys := np.npc(to, args) // 无解 if len(keys) == 0 { p.pushCloseSet(key) return nil } p.lock.Lock() defer p.lock.Unlock() // 在查找一次 fn, ok = p.m[key] if ok { return fn } fn = &Fn{} fn.queue = keys p.m[key] = fn p.All = append(p.All, key) sort.StringSlice(p.All).Sort() return fn }