我正在尝试将LuaJ与Scala一起使用。大多数事情都有效(实际上,如果你正确地完成它们,所有事情都会工作!)但是由于Scala的setter实现,设置对象值的简单任务变得异常复杂。
Scala的:
class TestObject {
var x: Int = 0
}
的Lua:
function myTestFunction(testObject)
testObject.x = 3
end
如果我执行包含此Lua函数的脚本或行并将TestObject的强制实例传递给myTestFunction,则会在LuaJ中导致错误。 LuaJ试图直接写入值,而Scala要求你通过隐式定义的setter(使用可怕的名字x_ =,这是无效的Lua,所以即使尝试将其称为函数也会使你的Lua无法解析)
正如我所说,有一些解决方法,例如定义自己的setter或使用@BeanProperty标记。他们只是编写应该更容易编写的代码:
的Lua:
function myTestFunction(testObject)
testObject.setX(testObject, 3)
end
有没有人知道让luaj隐式调用setter进行此类赋值的方法?或者我可能会在luaj源代码中查找或许实现这样的事情?
谢谢!
答案 0 :(得分: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的源代码以更好地满足您的需求,我快速浏览了文档和源代码,找到了this,this和this。我最好的猜测是,如果Scala需要一种不同的设置值的方式,line 71 of JavaInstance.java就是你需要改变的地方。
f.set(m_instance, CoerceLuaToJava.coerce(value, f.getType()));
答案 1 :(得分: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)