我在Scala中使用Drools Planner(用Java编写)时遇到了问题。 Drools规划器中的一个接口声明为:
public interface Score<S extends Score> extends Comparable<S>
然而,另一个界面使用“得分”作为原始类型:
public interface Solution {
Score getScore();
然后我想在Scala中实现这个接口:
class MySolution extends Solution {
def getScore: Score = ...
我收到编译错误:Scala编译器不允许编写'def getScore:Score'。当我尝试添加'Score [_]'或'Score [whatever]'编译器抱怨类型不兼容时。我该怎么办?
答案 0 :(得分:9)
编写一个Java类,作为Java接口所需内容与Scala允许内容之间的桥梁。
SolutionBridge.java:
abstract class SolutionBridge implements Solution {
public Score getScore() {
return scalaGetScore();
}
abstract Score<?> scalaGetScore();
}
SolutionScala.scala:
class SolutionScala extends SolutionBridge {
def scalaGetScore() = null.asInstanceOf[Score[_]]
}
答案 1 :(得分:4)
您省略的错误消息不是一个无关紧要的细节。重新“我也希望得到Scala的一些支持”,你也可以通过阅读错误信息选择参与这个过程,如果你不理解它们,在提问时包括它们而不是模糊地解释它们。
错误消息,它们很重要。即使他们感到困惑。特别是当他们感到困惑时。
以下是2.8.1中的错误:
a.scala:2: error: overriding method getScore in trait Solution of type ()Score[_ <: Score];
method getScore has incompatible type
def getScore: Score[_] = null
^
one error found
以下是trunk的错误:
a.scala:2: error: overriding method getScore in trait Solution of type ()Score[_ <: AnyRef];
method getScore has incompatible type
def getScore: Score[_] = null
^
one error found
那里有一个关键的区别,当我这样做时,它会导致它与trunk一起工作,因为错误信息指示我。
// this compiles with 2.9, but not with 2.8
class MySolution extends Solution {
def getScore: Score[_ <: AnyRef] = null
}
在java源代码中使用原始类型Score的方式(作为一个位置的类型构造函数,但在另一个位置具有隐含的存在类型参数,第二个外观限定第一个),这是一个奇迹,它可以在任何地方工作。你不想知道在编译器上已经造成了多少损害。如果原始类型能够正常工作会很好,但很多事情都会很好。有些事情是不可能的,有些事情是不可取的,有些事情需要太多的努力才能保持船只漂浮。原始类型赢得三冠王。
答案 2 :(得分:3)
下一版Drools Planner(5.2.0.M2)将fix this issue。 Here's the commit on git.
在某些情况下,人们希望定义自己的Score
实现(例如NurseRosterScore
实现HardAndSoftScore
),以便能够根据硬约束类型或软约束类型向用户显示什么在最佳解决方案中完全违反了。这一改变是使这更容易和更清洁的第一步(即使它已经成为可能)。
答案 3 :(得分:0)
您是否尝试过投射Score
:
val s = solution.getScore.asInstanceOf[Score[Int]]