Проверка времени компиляции для универсальных типов, которые различаются между this.type и другими типами - PullRequest
0 голосов
/ 18 декабря 2018

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

Следующий код компилируется и запускается как charm, как и ожидалось:

trait T1[A]
    {
        type ReturnType = this.type
        val returnValue : this.type = this
        def apply(_x : A) : ReturnType
    }
trait T2[A]
    extends T1[Option[A]]
        {
            def apply(_x : A) : ReturnType
        }
class C1[A]
    extends T1[A]
        {
            def apply(_x : A) : ReturnType = 
                {
                    // some functionality
                    returnValue
                }
        }
class C2[A]
    extends C1[Option[A]]
    with T2[A]
        {
            def apply(_x : A) : ReturnType = apply(Some(_x)) 
        }

Однако изменение строк типа и returnValue, например:

type ReturnType = String
val returnValue : String = ""

, приведет к следующему сообщению:

<pastie>:23: error: name clash between defined and inherited member:
def apply(_x: Option[A]): T2.this.ReturnType in trait T1 and
def apply(_x: A): T2.this.ReturnType at line 23
have same type after erasure: (_x: Object)String
                def apply(_x : A) : ReturnType
                    ^
<pastie>:38: error: name clash between defined and inherited member:
def apply(_x: Option[A]): C2.this.ReturnType in class C1 and
def apply(_x: A): C2.this.ReturnType at line 38
have same type after erasure: (_x: Object)String
                def apply(_x : A) : ReturnType = apply(Some(_x))
                    ^

Мое объяснение состоит в том, чтопроверки типов для this.type откладываются, так как при объявлении точный тип this.type неизвестен.Только супер-тип известен.

У меня есть два вопроса:

1) Правильно ли мое предположение?

2) Возможно, первый код работает как брелок, я подозреваю, чтовторой код также будет работать как шарм, но компилятор слишком охотно выполняет проверку типа.Почему нельзя сделать так, чтобы эта проверка также была отложена.Мое решение теперь состоит в том, чтобы дублировать код для моего второго класса, где я больше не расширяюсь от первого класса, но скопирую код для первого класса и добавлю дополнительную строку.

...