【问题标题】:Inherit Java class from Luaj从 Luaj 继承 Java 类
【发布时间】:2014-12-21 05:38:18
【问题描述】:

是否有可能在 Luaj 中让 Lua 类扩展 Java 类?我尝试在绑定类上使用getmetatable(),但显然它返回nil

这里,Wizard 是绑定到 Lua 的 Java 类,SetupWizard 是我要从Wizard 继承的 Lua 类。

function SetupWizard:new()
    local self = setmetatable({}, getmetatable(Wizard))
    return self
end

__index 分配给Wizard 的值也不起作用。

SetupWizard 定义:

SetupWizard = {
    host = nil,
    user = nil,
    password = nil,
    database = nil,
    mySqlTables = {
        users = nil,
    },
}
SetupWizard.__index = Wizard

... SetupWizard methods here

【问题讨论】:

  • 我对 LuaJ 了解不多,但很可能Wizard 本身就是一个用户数据,它有自己的__index 方法,如果它被分配为__index 表,则不会被检查另一个对象。您可能会尝试的只是将类的元表的__index 分配给从Wizard 获取的函数,例如function idx(self, k) return Wizard[k] end

标签: java lua luaj


【解决方案1】:

LuaJ 在处理诸如从 java 中导入类之类的事情方面相当灵活。 你没有具体说明你是如何做到这一点的,所以我假设你已经通过创建一个library of Java Functions 作为一个桥梁来构建一个你可以需要的模块(使用require"moduleName"),就像这样:

import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;


/*
 * When require"module name" is called in luaJ it also searches for java classes with a classname that matches
 * the given module name that inherit from LuaFunction and have a default constructor, it then
 * calls the method call(LuaValue moduleName, LuaValue globalEnviroment) passing the module name string and
 * global environment as LuaValues and returning the return value of this call as it's own. 
 * 
 */

public class Example extends TwoArgFunction{

    @Override
    public LuaValue call(LuaValue modname, LuaValue globalEnv) {
        // Creates a table to place all our functions in
        LuaValue table = LuaValue.tableOf();

        // Sets the value 'name' in our table to example. This is used in the example function
        table.set("name", "example");
        // Sets the value 'exampleMethod' in our table to the class of type OneArgFunction
        // we created below
        table.set("exampleMethod", exampleMethod);

        //Finally returns our table. This value is then returned by require.
        return table;
    }


    /* Creates a function that takes one arg, self.

      This emulates the creation of a method in lua and can be called,
      when added to a table, as table:exampleMethod().
      This is possible as in Lua the colon in functions is
      Syntactic suger for object.function(object) 

    */
    OneArgFunction exampleMethod = new OneArgFunction() {

        @Override
        public LuaValue call(LuaValue self) {

            if(self.istable()) {
                return self.get("name");
            }

            return NIL;
        }
    };

}

这可以在你的 Lua 代码中使用如下:

--Imports the class Wrapper we created
example = require"Example"
--Prints the return value of calling exampleMethod
print("The name of the class is: "..example:exampleMethod())


--And then used as an index like so
example2 = setmetatable({},{__index=example})

example2.name = "example2"

print("The name of the class is: "..example2:exampleMethod())

正如我在答案顶部所说,LuaJ 在如何处理这些事情方面很灵活,这只是我会做的方式。

由于我的声誉,我无法发表评论询问您如何进行导入 LuaJ 中的 Java 类,请随时在对此答案的评论中澄清。

【讨论】:

    【解决方案2】:

    你的基于 Java 的 LuaJ 模块需要返回一个表,而你使用

    local SetupWizard = require("SetupWizard")
    local Wizard = {}
    setmetatable(Wizard, {__index=SetupWizard})
    --optionally create single metatable for all Wizard instances: local wizardMetaTable = {_index=Wizard}
    function Wizard:new()
      local T = {}
      setmetatable(T, {__index=Wizard})
      -- setmetatable(T, wizardMetaTable)
      -- this increases performance by using one metatable for all wizards.
      return T
    end
    

    【讨论】:

      猜你喜欢
      • 2011-10-01
      • 2012-02-25
      • 2015-11-16
      • 2015-03-14
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多