Почему конкретная реализация абстрактного типа не может быть использована для вывода ClassTag? - PullRequest
2 голосов
/ 21 июня 2019

Учитывая следующий код:

object DelayedClassTagInference {

  trait SS {

    type TT <: Any

    implicit val ctg: ClassTag[TT] = implicitly[ClassTag[TT]]

    val fakeCtg: ClassTag[None.type] = implicitly[ClassTag[None.type]]

  }

  class Sub1 extends SS {

    override final type TT = Int
  }

  class Sub2 extends SS {

    override final type TT = Double
  }

  class Sub3 extends SS {

    override final type TT = String
  }
}

class DelayedClassTagInference extends FunSpec {

  import DelayedClassTagInference._

  it("") {

    val sub1 = new Sub1()
    println(sub1.fakeCtg)
    println(sub1.ctg)
  }
}

Когда инициализируются Sub1 и Sub2, тип TT уже определен, поэтому ClassTag [Int] и ClassTag [Double] могут быть легко выведены с помощью правил класса типов.

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

scala.None$
null

Таким образом, значение ctg равно нулю, кроме запуска исключения NullPointerException, это также не имеет смысла.Это сумка для скалы, которую нужно починить позже?

1 Ответ

3 голосов
/ 21 июня 2019

Удалите модификатор implicit для val ctg, и вы увидите, что ваш код не компилируется.Вы не должны определять неявное ClassTag / TypeTag / WeakTypeTag вручную, они должны генерироваться компилятором автоматически, когда тип известен.

На самом деле, когда вы вызываете implicitly[ClassTag[TT]] неявное val ctg: ClassTag[TT] выиспользуется определение прямо сейчас, поэтому оно null во время выполнения.

Последствия разрешаются во время компиляции, и, когда вы вызываете sub1.ctg, разрешение вызова .ctg происходит во время выполнения (этокак работает полиморфизм подтипов).Во время компиляции еще не известно, что это Sub1#ctg.


Замените

implicit val ctg: ClassTag[TT] = implicitly[ClassTag[TT]] 

на

def ctg(implicit tag: ClassTag[TT]): ClassTag[TT] = implicitly[ClassTag[TT]] 

, и у вас будет Intво время выполнения вместо null.

...