Создать универсальный класс (с подстановочными типами) и несколько конструкторов - PullRequest
2 голосов
/ 17 марта 2011

Я довольно новичок в Scala (2.8) и вот что я пытаюсь выразить в Scala:

Мне нужно определить класс, который (из-за совместимости с библиотекой Java) реализует Comparable;его универсальный тип должен быть Comparable с самим собой или суперклассом

Мне также нужно иметь конструктор без аргументов вместе с другим, который использует универсальный параметр

Я написал простой эквивалентчто я пытаюсь получить в Java:

public class MyComparable<T extends Comparable<? super T>>{
    public MyComparable() {}

    public MyComparable(T a){
        System.out.println(a);
    }
}

Я могу без проблем импортировать этот класс в REPL Scala и создать его экземпляр.

Это то, что я пишу в Scalaчтобы попытаться выполнить одно и то же:

import java.lang.Comparable

class MyComparable[T <: Comparable[_>:Tb],Tb]()(implicit ev: T=:=Tb) {
    def this(a: T) = {
        this()
        println(a)
    }
}

Я пробовал оба, используя конструктор no-args в качестве по умолчанию, или используя конструктор с аргументом T: в обоих случаях я получаю error: could not find implicit value for parameter ev: =:=[T,Tb] встрока 5

Afaik, =: = импортируется по умолчанию из scala.Predef (и фактически этот код работает нормально только с одним конструктором)

Ответы [ 3 ]

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

Вы слишком усложняете проблему - хотя было бы хорошо, если бы у Java была разница между объявлениями и сайтами, что могло бы все это спорить. В любом случае, вот эквивалентный код:

class MyComparable[T <: Comparable[T2], T2 >: T]() {
    def this(a: T) = {
        this()
        println(a)
    }
}

Предполагается, что в нем не используется необработанный тип, и вместо двух он имеет два параметра типа. Опять же, возникает вопрос о том, чего вы на самом деле пытаетесь достичь с помощью этой декларации. Интересно, что вы на самом деле хотите, так это:

import scala.annotation.unchecked.uncheckedVariance
class MyComparable[-T <: Comparable[T @uncheckedVariance]]() {
    def this(a: T) = {
        this()
        println(a)
    }
}

Я говорю Скале игнорировать дисперсию выше на свой страх и риск, потому что я предполагаю, что Comparable действительно может быть противоположным. Следующий код указывает, что это действительно так:

scala> trait Cp[-T] {
     |   def compareTo(other: T): Int
     | }
defined trait Cp

scala> class MyComparable[-T <: Cp[T]] {
     | }
defined class MyComparable
3 голосов
/ 17 марта 2011

Не совсем уверен, что вы пытаетесь сделать, но вы можете сделать это так:

import java.lang.Comparable

class MyComparable[T <: Comparable[_>:Tb],Tb]()(implicit ev: T=:=Tb) {
  def this(a: T)(implicit ev: T=:=Tb) = {
    this()
    println(a)
  }
}
2 голосов
/ 04 апреля 2011

Это по-прежнему не то же самое, что код Java, который я опубликовал, но он кажется достаточно близким и более чистым, чем другие решения:

import java.lang.Comparable
class MyComparable[T <: Comparable[T]]() {
    def this(a: Comparable[_ >: T]) = {
        this()
        println(a)
    }
}

Вот несколько разных ссылок, которые я прочитал с тех пор, когдаЯ застрял с этой проблемой, которая может помочь кому-то еще с подобной проблемой:

Когда в Scala требуется @uncheckedVariance и почему он используется в GenericTraversableTemplate?

, чтобы понять, что делает =: = действительно делает

http://programming -scala.labs.oreilly.com / ch12.html # VarianceUnderInheritance

http://www.scala -lang.org / node / 129

Стирание типа и другие низкоуровневые сведения об универсальных элементах Java

http://www.scala -lang.org / узел / 124

http://scalada.blogspot.com/2008/01/existential-types.html

http://lamp.epfl.ch/~emir/bqbase/2007/06/13/existentials.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...