使用LuaJ和Scala

我正在尝试将LuaJ与Scala一起使用。大多数东西都能正常运作(实际上,如果正确操作,则所有东西都能正常运作!),但由于Scala的setter实现,设置对象值的简单任务变得异常复杂。

Scala:

class TestObject {
  var x: Int = 0
}

Lua:

function myTestFunction(testObject)
  testObject.x = 3
end

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

正如我所说,有解决方法,例如定义自己的setter或使用@BeanProperty标记。它们只会让本应易于编写的代码变得更加复杂:

Lua:

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

有人知道如何使luaj在这样的赋值中隐式调用setter的方法吗?或者在luaj源代码中可以查找哪里以实现这样的事情?

谢谢!

点赞
用户828255
用户828255

我必须承认,我对LuaJ不是太熟悉,但是关于你的问题,我首先想到的是将对象封装在代理表中,以便与API交互。根据你的需要,这个解决方案可能是最好的,也可能只是一个好的临时修复方法。

local mt = {}

function mt:__index(k)
    return self.o[k] -- 在这里定义如何获取器工作。
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的源代码以更好地适应你的需要,我已经快速查看了文档和源代码,并找到了 这个这个这个。我的最佳猜测是,如果Scala需要设置值的不同方式,你会在 JavaInstance.java 的第71行 找到需要更改的内容。

    f.set(m_instance, CoerceLuaToJava.coerce(value, f.getType()));
2013-11-19 23:09:17
用户2556943
用户2556943

也许你应该使用以下这种语法:

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-14 15:26:59