在Drools右侧创建新的Scala对象
由于我在Drools中使用Scala不可变对象,为了更新事实,我需要创建一个新对象来替换它。我已经为要调用的规则编写了一个Scala方法,它只返回这样一个对象 我的问题是,在Drools规则的“then”部分中定义新的Scala case类对象的语法是什么?我已经尝试过类似于下面的语法,我在某处看到过,但它似乎也不起作用…(即使是像字符串这样的标准类型) 目前对Drools+Scala的支持和文档似乎相当有限。有什么想法吗 (仅供参考,我已经阅读了以下问题,它不是同一个查询…我的对象不是全局对象:) DRL文件如下:在Drools右侧创建新的Scala对象,scala,drools,Scala,Drools,由于我在Drools中使用Scala不可变对象,为了更新事实,我需要创建一个新对象来替换它。我已经为要调用的规则编写了一个Scala方法,它只返回这样一个对象 我的问题是,在Drools规则的“then”部分中定义新的Scala case类对象的语法是什么?我已经尝试过类似于下面的语法,我在某处看到过,但它似乎也不起作用…(即使是像字符串这样的标准类型) 目前对Drools+Scala的支持和文档似乎相当有限。有什么想法吗 (仅供参考,我已经阅读了以下问题,它不是同一个查询…我的对象不是全局对象
package resources
import function drools.RuleFunctions.*
import order.Cart
import order.CartLine
import generic.Amount
import scala.*
import scala.Option
import org.kie.api.runtime.KieRuntime
import java.math.BigDecimal
dialect "mvel"
rule "Eval Cart Line"
agenda-group "init"
auto-focus true
dialect "mvel"
lock-on-active true
salience 1000
when
$cart: Cart($line: lines(), amount == null) //If Cart found with lines, but with no cart amount set
$o : CartLine($id : ref, $qty: quantity) from $line
then
Cart $newB = updateLineAmount($cart, $id, $qty, kcontext.getKieRuntime())
update(kcontext.getKieRuntime().getFactHandle($cart),$newB)
end
rule "Product 20% Discount"
agenda-group "LineDiscount"
auto-focus true
dialect "mvel"
lock-on-active true
salience 900
when
$cart: Cart($line : lines, amount == null)
$o : CartLine(ref == "1234", amount != null ) from $line
then
Cart $newB = addLineDiscount($cart, $o, 20.0, kcontext.KieRuntime())
update(kcontext.getKieRuntime().getFactHandle($cart), $newB)
end
更新
object RuleFunctions {
def updateLineAmount(cart: Cart, id: String, qty: Int, krt: KieRuntime): Cart= {...}
def addLineDiscount(cart: Cart, bLine : CartLine, discPerc: Double, krt: KieRuntime): Cart= {...}
}
从Scala对象类型导入方法在Drools中可能会有问题。原因很简单,与Java相比,Scala中不存在
static
方法。这是因为Scala对纯面向对象语言的含义有更严格的解释
这意味着,无论何时尝试使用Droolsimport函数
语法,它都找不到任何要导入的静态方法。因此,Drools编译器会抱怨对Scala单例对象类型中包含的方法的任何引用
解决这一问题的一个办法是用Java编写将要在DRLs中使用的任何类,您可以在其中显式定义静态方法。Scala编译器会很高兴地将它们与您的Scala类一起编译。如果MyObject被定义为case类,并且您的returnNewMyObject返回它的一个实例,那么我看不出问题所在。请澄清……是的,错误消息中清楚地显示了这一点。编译器对addLineDiscount一无所知。您必须给它一个句柄/引用,指向具有该方法的对象。你试过了吗?你应该关闭严格模式。评论不用于扩展讨论;这段对话已经结束了。我不确定Drools能不能和Scala一起玩。问题是Scala对象类型中的方法是隐式静态的;这就是把它们放在那里的全部意义。在Java中,必须显式声明该方法是静态的。我认为,当Scala对象类型被编译成字节码时,它与具有静态方法的等效Java类不同。更具体地说,我认为Drools无法发现这样一个事实,即存在从Scala对象类型导入的静态方法。@Placboom I.K.和GroomedGorilla,我从Mark Proctor自己那里得知Drools团队尚未验证Scala与Drools的结合。在下一个小版本(6.1)之后,有一个这样做的计划。没有声明说这是理所当然的,也没有其他反应。你知道,或者可以查一查,这里讨论了什么。
object RuleFunctions {
def updateLineAmount(cart: Cart, id: String, qty: Int, krt: KieRuntime): Cart= {...}
def addLineDiscount(cart: Cart, bLine : CartLine, discPerc: Double, krt: KieRuntime): Cart= {...}
}