Реализация методов с необработанными типами в Scala - PullRequest
7 голосов
/ 12 марта 2011

У меня проблема с использованием Drools Planner (написана на Java) в Scala.Один из интерфейсов в планировщике Drools объявлен как:

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 [_]» или «Score [что угодно]» жалуется на несовместимость типов.Что мне делать?

Ответы [ 4 ]

9 голосов
/ 12 марта 2011

Напишите класс 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[_]]
}
4 голосов
/ 13 марта 2011

Сообщение об ошибке, которое вы пропустили, не является посторонней деталью.«Я бы также ожидал поддержки от 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

Вот ошибка с транком:

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

Естьздесь есть ключевое отличие, которое способствует тому, почему он работает с транком, когда я делаю так, как подсказывает мне сообщение об ошибке.

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

Способ использования необработанного типа Score в исходном коде Java (в качестве конструктора типа водно местоположение, но с подразумеваемым аргументом экзистенциального типа в другом, со вторым появлением, ограничивающим первое), удивительно, что это работает где угодно.Вы не хотите знать, какой ущерб от такого рода вещей уже нанесен компилятору.Это правда, что было бы неплохо, если бы просто работали необработанные типы, но многие вещи были бы хорошими.Некоторые вещи невозможны, некоторые нежелательны, а некоторые требуют слишком больших усилий от крошечного числа людей, удерживающих корабль на плаву.Сырые виды выигрывают тройную корону.

3 голосов
/ 13 марта 2011

В следующей версии Drools Planner (5.2.0.M2) исправит эту проблему . Вот коммит на git.

В некоторых случаях люди хотят определить свою собственную реализацию Score (например, NurseRosterScore Implements HardAndSoftScore), чтобы иметь возможность показатьпользователь по типу жесткого или мягкого ограничения, что именно нарушается в лучшем решении.Это изменение - первый шаг к тому, чтобы сделать это проще и чище (хотя это уже возможно).

0 голосов
/ 12 марта 2011

Вы пытались разыграть Score:

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