1

我正在尝试将 LuaJ 与 Scala 一起使用。大多数事情都可以工作(实际上,如果你做对了,所有事情都可以工作!)但是由于 Scala 的 setter 实现,设置对象值的简单任务变得异常复杂。

斯卡拉:

class TestObject {
  var x: Int = 0
}

卢阿:

function myTestFunction(testObject) 
  testObject.x = 3
end

如果我执行包含此 Lua 函数的脚本或行并将 TestObject 的强制实例传递给 myTestFunction,这会导致 LuaJ 中的错误。LuaJ 正在尝试直接写入该值,而 Scala 要求您通过隐式定义的 setter(使用可怕的名称 x_=,这不是有效的 Lua,因此即使尝试将其作为函数调用也会使您的 Lua 无法解析) .

正如我所说,有一些解决方法,例如定义您自己的设置器或使用@BeanProperty 标记。他们只是使应该易于编写的代码变得更加复杂:

卢阿:

function myTestFunction(testObject) 
  testObject.setX(testObject, 3)
end

有谁知道让 luaj 隐式调用 setter 进行此类分配的方法?或者我可能会在 luaj 源代码中查看以实现这样的事情?

谢谢!

4

2 回答 2

1

我必须承认我对 LuaJ 不太熟悉,但是关于您的问题,我首先想到的是将对象包装在代理表中以简化与 API 的交互。根据您的需求,此解决方案可能是最好的,也可能不是最好的,但它可能是一个很好的临时解决方案。

local mt = {}

function mt:__index(k)
    return self.o[k] -- Define how your getters work here.
end

function mt:__newindex(k, v)
    return self.o[k .. '_='](v) -- "object.k_=(v)"
end

local function proxy(o)
    return setmetatable({o = o}, mt)
end

-- ...

function myTestFunction(testObject) 
    testObject = proxy(testObject)
    testObject.x = 3
end

我相信这可能是解决您的问题的侵入性最小的方法。至于修改 LuaJ 的源代码以更好地满足您的需求,我快速浏览了文档和源代码,发现了 thisthisthis。我最好的猜测是 JavaInstance.java 的第 71 行是您可以找到需要更改的地方,如果 Scala 需要不同的设置值的方式。

    f.set(m_instance, CoerceLuaToJava.coerce(value, f.getType()));
于 2013-11-19T23:09:17.030 回答
0

也许您应该使用方法语法:

testObject:setX(3)

注意冒号“:”而不是点“。” 在某些编辑器中很难区分。

这与函数调用的效果相同:

testObject.setX(testObject, 3)

但更具可读性。

它还可以用于调用类的静态方法:

luajava.bindClass("java.net.InetAddress"):getLocalHost():getHostName()

':' 左边的部分被计算一次,所以像这样的语句

x = abc[d+e+f]:foo()

将被评估为

local tmp = abc[d+e+f]
x = tmp.foo(tmp)
于 2014-01-14T15:26:59.327 回答