Параметрический тип + функция требует строки в качестве второго параметра?

StackOverflow https://stackoverflow.com/questions/3127934

Вопрос

class TestClass[T](val x: T) { def +(other: TestClass[T]) = x + other.x }

Это определение дает мне следующую ошибку компиляции:

Ошибка: несоответствие типа;
Найдено: Т.
Требуется: строка
def + (Другое: testclass [t]) = x + white.x

Разве невозможно использовать INT или Double в качестве параметра типа и использование добавления в Scala ??

Это было полезно?

Решение

Во-первых, сообщение об ошибке вводит в заблуждение. Scalac пытается найти метод + по значению x. Отказ Это не существует на типе T, что может быть любой тип вообще. Это называется неограниченным типом параметра. Таким образом, он пытается подать заявку и неявное представление. Predef.any2stringadd соответствует законопроекту.

Вы можете отключить это неявное преобразование и увидеть реальную ошибку:

 ~/code/scratch: cat plus.scala 
import Predef.{any2stringadd => _, _}

class TestClass[T](val x: T) { 
  def +(other: TestClass[T]) = x + other.x 
}
 ~/code/scratch: scalac plus.scala 
plus.scala:4: error: value + is not a member of type parameter T
  def +(other: TestClass[T]) = x + other.x 
                               ^
one error found

В C ++ проверка типа выполняется после предоставления параметра типа на каждом сайте вызова. Так что этот стиль кода будет работать. В SCALA общий метод должен быть типа проверяется по его определению, основываясь только на границах абстрактных типов.

Как предложено VONC, вы можете предоставить контекст, связанный на параметре типа T ограничить, если к типу, который имеет соответствующий экземпляр Numeric черта.

class TestClass[T: Numeric](val x: T) { 
  def +(other: TestClass[T]): T = {
    val num = implicitly[Numeric[T]]
    import num._
    x + other.x
  }
}

Вот как это выглядит со всеми недостатками, сделанными явными:

class TestClass[T]{
  implicit <paramaccessor> private[this] val evidence$1: Numeric[T] = _;
  def this(x: T)(implicit evidence$1: Numeric[T]): TestClass[T] = {
    TestClass.super.this();
    ()
  };
  def +(other: TestClass[T]): T = {
    val num: Numeric[T] = scala.Predef.implicitly[Numeric[T]](TestClass.this.evidence$1);
    import num._;
    num.mkNumericOps(TestClass.this.x).+(other.x)
  }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top