golang 动态执行脚本

golang 需要编译,但是 有时候我需要动态语言的特性,就需要动态执行脚本

更多

gopher-luar 和 starlark-go-lib 已经把在 gopher-lua 和 starlark-go 中使用 go 语言的第三方包变得极其容易。当然可以做得更好,我们可以支持类似 import 的语句,自动下载第三方包,并作语法分析,生成到 gopher-lua 和 starlark-go 中作为第三方包,逻辑上并不困难。不过真的有必要做到这一步吗,因为作为 repl 工具, gomacro 已经做得足够好了,还是止步于此吧。

参考文档

https://github.com/robertkrimen/otto

这里我使用 otto 来搞

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package main

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

//go get -u go.starlark.net/cmd/starlark
func Test1 (t *testing.T) {
	var cmd string = `
	    console.log("123456");
		 
        /* var arr = [1,2,3]; */
        var arr = getList();
        console.log(arr);
        for(var i=0;i<arr.length;i++ ){
           console.log(arr[i]);
        }
        var ok = "it is OK ";

        function isOK(input ) {
           if (input == null) return false;
           //数组长度大于等于3;
           return input.length && input.length>3;
        }
	`

	//fmt.Println(cmd)

	vm := otto.New()
	vm.Set("getList", func(call otto.FunctionCall) otto.Value {
		w := []int{1,3,3}
		res , _ := vm.ToValue(w)
		return res
	})

	_,err := vm.Run(cmd)
	get, err := vm.Get("ok")
	if err != nil {
		panic(err)
	}
	fmt.Println(get)
	 
	s := []int{1,2,3,4,5}
	res, err := vm.Call("isOK", s)
	if err!=nil {
		panic(err)
	}
	fmt.Printf("res = %#v \n",res)

}


/*

=== RUN   Test1
123456
1,3,3
1
3
3
it is OK 
res = otto.Value{kind:4, value:false} 
--- PA

*/

我们可以在脚本里面定义一些钩子方法,

比如写爬虫的时候,调用 这些方法判断,也可以将 爬虫的 api 接口连接写到钩子方法里面,这样就很好。