设为首页 加入收藏

TOP

浅谈如何使用 github.com/yuin/gopher-lua(一)
2023-07-23 13:28:05 】 浏览:92
Tags:谈如何 github.com/yuin/gopher-lua

最近熟悉 go 项目时,发现项目中有用到 github.com/yuin/gopher-lua 这个包,之前并没有接触过,特意去看了官方文档和找了些网上的资料,特此记录下。

本次介绍计划分为两篇文章,这一次主要介绍 github.com/yuin/gopher-lua 这个包的介绍以及基础使用,下一边将介绍 github.com/yuin/gopher-lua 是如何在项目中使用的。如有不对的地方,请不吝赐教,谢谢。

文章中的 gopher-lua 如果没有特别说明,即为:github.com/yuin/gopher-lua。

1、 gopher-lua 基础介绍

我们先开看看官方是如何介绍自己的:

GopherLua is a Lua5.1(+ goto statement in Lua5.2) VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting language with extensible semantics . It provides Go APIs that allow you to easily embed a scripting language to your Go host programs.

GopherLua是一个Lua5.1(Lua5.2中的+goto语句)虚拟机和用Go编写的编译器。GopherLua与Lua有着相同的目标:成为一种具有可扩展语义的脚本语言。它提供了Go API,允许您轻松地将脚本语言嵌入到Go主机程序中。

看上面的翻译还是有点抽象,说说自己的理解。 github.com/yuin/gopher-lua 是一个纯 Golang 实现的 Lua 虚拟机,它能够很轻松的在 go 写的程序中调用 lua 脚本。另外提一嘴,使用插件后,也能够在 lua 脚本中调用 go 写好的代码。挺秀的!

接下来我们看一看, github.com/yuin/gopher-lua 的性能如何,这里就直接引用官方自己做的测试来介绍。详情见 wiki page 链接。点进链接过后,发现性能还不错,执行效率和性能仅比 C 实现的 bindings 差点。

官方测试例子是生成斐波那契数列,测试执行结果如下:

prog time
anko 182.73s
otto 173.32s
go-lua 8.13s
Python3.4 5.84s
GopherLua 5.40s
lua5.1.4 1.71s

2、 gopher-lua 简单使用

下面的介绍,都是基于 v1.1.0 版本进行的。

go get github.com/yuin/gopher-lua@v1.1.0

Go的版本需要 >= 1.9

2.1 gopher-lua 中的 hello world

这里写一个简单的程序,了解 gopher-lua 是如何使用的。

package main

import (
	lua "github.com/yuin/gopher-lua"
)

func main() {
	// 1、创建 lua 的虚拟机
	L := lua.NewState()
	// 执行完毕后关闭虚拟机
	defer L.Close()
	// 2、加载fib.lua
	if err := L.DoString(`print("hello world")`); err != nil {
		panic(err)
	}

}

执行结果:

hello world

看到这里,感觉没啥特别的地方,接下来,我们看一看 gopher-lua 如何调用事先写好的 lua脚本

fib.lua 脚本内容:

function fib(n)
    if n < 2 then return n end
    return fib(n-1) + fib(n-2)
end

main.go

package main

import (
	"fmt"
	lua "github.com/yuin/gopher-lua"
)

func main() {
	// 1、创建 lua 的虚拟机
	L := lua.NewState()
	defer L.Close()
	// 加载fib.lua
	if err := L.DoFile(`fib.lua`); err != nil {
		panic(err)
	}
	// 调用fib(n)
	err := L.CallByParam(lua.P{
		Fn:      L.GetGlobal("fib"), // 获取fib函数引用
		NRet:    1,                  // 指定返回值数量
		Protect: true,               // 如果出现异常,是panic还是返回err
	}, lua.LNumber(10)) // 传递输入参数n
	if err != nil {
		panic(err)
	}
	// 获取返回结果
	ret := L.Get(-1)
	// 从堆栈中扔掉返回结果
    // 这里一定要注意,不调用此方法,后续再调用 L.Get(-1) 获取的还是上一次执行的结果
    // 这里大家可以自己测试下
	L.Pop(1)
	// 打印结果
	res, ok := ret.(lua.LNumber)
	if ok {
		fmt.Println(int(res))
	} else {
		fmt.Println("unexpected result")
	}
}

执行结果:

55

从上面我们已经能够感受到部分 gopher-lua 的魅力了。接下来,我们就一起详细的学习学习 gopher-lua

2.2 gopher-lua 中的数据类型

All data in a GopherLua program is an LValue . LValue is an interface type that has following methods.

GopherLua程序中的所有数据都是一个LValue。LValue是一种具有以下方法的接口类型。

  • String() string
  • Type() LValueType
// value.go:29

type LValue interface {
	String() string
	Type() LValueType
	// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
	assertFloat64() (float64, bool)
	// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
	assertString() (string, bool)
	// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
	assertFunction() (*LFunction, bool)
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇《Go 精进之路》 读书笔记 (第一.. 下一篇密码学奇妙之旅、03 HMAC单向散列..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目