在 Scala 中实现具有原始类型的方法

发布于 2024-10-21 06:09:52 字数 513 浏览 3 评论 0原文

我在 Scala 中使用 Drools Planner(用 Java 编写)时遇到问题。 Drools planner 中的一个接口声明为:

public interface Score<S extends Score> extends Comparable<S>

然而另一个接口使用“Score”作为原始类型:

public interface Solution {
    Score getScore();

然后我想在 Scala 中实现此接口:

class MySolution extends Solution {
    def getScore: Score = ...

我得到一个编译错误: Scala 编译器不允许只编写 'def getScore:分数'。当我尝试添加“Score[_]”或“Score[whatever]”时,编译器抱怨类型不兼容。我应该怎么办?

I have a problem in using Drools Planner (written in Java) in Scala. One of interfaces in Drools planner is declared as:

public interface Score<S extends Score> extends Comparable<S>

However another interface uses 'Score' as a raw type:

public interface Solution {
    Score getScore();

Then I'd like to implement this interface in Scala:

class MySolution extends Solution {
    def getScore: Score = ...

And I get a compilation error: Scala compiler disallows writing just 'def getScore: Score'. When I try adding 'Score[_]' or 'Score[whatever]' compiler complains about type incompatibility. What should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

独闯女儿国 2024-10-28 06:09:52

编写一个 Java 类作为 Java 接口要求和 Scala 允许的之间的桥梁。

SolutionBridge.java:SolutionScala.scala

abstract class SolutionBridge implements Solution {
    public Score getScore() {
        return scalaGetScore();
    }

    abstract Score<?> scalaGetScore();
}

class SolutionScala extends SolutionBridge {
    def scalaGetScore() = null.asInstanceOf[Score[_]]
}

Write a Java class to serve as a bridge between what the Java interface requires and what Scala allows.

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[_]]
}
鹤舞 2024-10-28 06:09:52

您省略的错误消息不是无关的细节。关于“我还希望 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
}

原始类型 Score 在 java 源代码中的使用方式(在一个位置作为类型构造函数,但在另一个位置具有隐含的存在类型参数,第二个外观限制第一个外观),它在任何地方都可以工作,这真是一个奇迹。您不想知道容纳此类事情已经对编译器造成了多少损害。确实,如果原始类型能够正常工作那就太好了,但很多事情都会更好。有些事情是不可能的,有些事情是不可取的,有些事情需要极少数人付出太多的努力才能让船保持漂浮。原始类型赢得三冠王。

The error message which you omitted is not an extraneous detail. Re "I would also expect some support from Scala on this", you might also opt to participate in the process by reading the error messages and, if you don't understand them, include them when asking a question rather than vaguely paraphrasing them.

Error messages, they're important. Even when they're confusing. Especially when they're confusing.

Here is the error in 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

Here is the error with 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

There is a key difference there, which contributes to why it works with trunk when I do as the error message instructs me.

// this compiles with 2.9, but not with 2.8
class MySolution extends Solution {
  def getScore: Score[_ <: AnyRef] = null
}

The way the raw type Score is being used in the java source (as a type constructor in one location but with an implied existential type argument in another, with the second appearance bounding the first) it's a wonder it works anywhere. You don't want to know how much damage accomodating this sort of thing has already inflicted on the compiler. It's true that it would be nice if raw types just worked, but many things would be nice. Some things are not possible, some things are not desirable, and some things require too much effort from the tiny number of people keeping the ship afloat. Raw types win the triple crown.

昔梦 2024-10-28 06:09:52

Drools Planner (5.2.0.M2) 的下一个版本将修复此问题
这是 git 上的提交。

在某些情况下,人们想要定义自己的 < code>Score 实现(例如 NurseRosterScore 实现 HardAndSoftScore),能够向用户显示每个硬约束或软约束类型中到底违反了什么最佳解决方案。这一改变是使这一过程变得更容易、更干净的第一步(尽管这已经是可能的)。

The next release of Drools Planner (5.2.0.M2) will fix this issue.
Here's the commit on git.

In some cases, people want to define their own Score implementation (for example NurseRosterScore implements HardAndSoftScore), to be able to show to the user per hard or soft constraint type what exactly is violated in the best solution. This change is the first step to make that easier and cleaner (even though it's already possible).

苯莒 2024-10-28 06:09:52

您是否尝试过投射Score

val s = solution.getScore.asInstanceOf[Score[Int]]

Have you tried to cast Score:

val s = solution.getScore.asInstanceOf[Score[Int]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文