那種動態呼叫技術效率最高?

fanyang發表於2016-12-02
//根據json
{"name":"年齡","opera":"==","value":25},
{"name":"性別","opera":"==","value":"男性"}
//生成程式碼
func GetResultdata map[string]interface{}string{
    if data["年齡"]==25&&data["性別"]=="男性" {
        return "小明"
    }
}

// 前端傳遞過來的json
data:=map[string]interface{}{
    "年齡":25,
    "性別":"男性",
}

//在api裡動態呼叫生成的程式碼
func GetOne(data map[string]interface{})(string,error){
    return GetResult(data),nil
}

1.使用第三方 otto 包可以嵌入 js 程式碼,不支援動態載入

//生成
package test

import (
    "github.com/robertkrimen/otto"
)

type client struct {
    VM *otto.Otto
}

func NewOtto() *client {
    return &client{VM: otto.New()}
}
func (c *client) Run() string {
    c.VM.Run(`
        if (年齡==25&&性別=="男性"){
            result="小明"
        }
    `)
    v, err := c.VM.Get("result")
    if err != nil {
        panic(err)
    }
    value, err := v.ToString()
    if err != nil {
        panic(err)
    }
    return value
}

//呼叫
import (
    "test"
    )
func GetOne(data map[string]interface{})(string,error){
    js := test.NewOtto()
    for k, v := range data {
        js.VM.Set(k, v)
    }
    return js.Run(), nil
}

2.使用偽包 C 可以嵌入 c 程式碼

// 生成

// foo.h
char* getResult(int,char*);

// foo.c
#include "foo.h"

char* getResult(int age,char* sex) {
    if (age==25&&sex=="男性"){
        return "小明";
    }
}

// 編譯
$> gcc -c foo.c
$> ar rv libfoo.a foo.o
//呼叫

package main
// #cgo LDFLAGS: -L ./ -lfoo
// #include <stdio.h>
// #include <stdlib.h>
// #include "foo.h"
import "C"

func main() {
    sex:=C.CString("男性")
    result:=C.GoString(C.getResult(25,sex))//小明
}

3.格式化後編譯成包,不支援動態載入

// 生成
package test
type business struct{
   data map[string]interface{}
}
func NewData(value map[string]interface{})*business{
    return &business{data:value}
}
func (b *business) GetResult()string{
  if b.data["年齡"]==25&&b.data["性別"]=="男性"{
   return "小明"
  }
}
// 編譯
import "os/exec"
exec.Command("gofmt")
exec.Command("go", "build",filePath)

// 呼叫
import (
    "test"
    "reflect"
    "errors"
    )
func GetOne(data map[string]interface{})(string,error){
    obj:=reflect.ValueOf(test.NewData(data))
    fun:=obj.MethodByName("GetResult")
    if !fun.IsValid(){
        return "",errors.New("GetResult不存在")
    }
    return fun.Call(nil)[0].String(),nil
}

還有沒有其他動態呼叫方法?

更多原創文章乾貨分享,請關注公眾號
  • 那種動態呼叫技術效率最高?
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章