2017-01-04 6 views
0

Ниже у меня есть целенаправленно сложное приложение Hello World, в котором я не могу понять всю жизнь, почему метод buildAndRun2 просто не компилируется.Путаница над фактическим типом абстрактного абстрактного типа

abstract class BaseFactoryOf[A]{ 
    type TheType 
    def make: TheType 
} 

abstract class FactoryOf[A] extends BaseFactoryOf[A]{ 
    final type TheType = A 
} 

class HelloWorld { 
    def execute: String = "Hello World!" 
} 

class HelloWorldFactory extends FactoryOf[HelloWorld] { 
    def make: TheType = new HelloWorld 
} 

def buildAndRun1[T <: BaseFactoryOf[_],B](factory: T)(f: T#TheType => B): B ={ 
    f(factory.make) 
} 

def buildAndRun2[T <: FactoryOf[_],B](factory: T)(f: T#TheType => B): B ={ 
    f(factory.make) 
} //This doesn't compile due to a type mismatch error. But Why?! 

//Client Code 
buildAndRun1(new HelloWorldFactory)(i => i.execute) // This Works! 
buildAndRun2(new HelloWorldFactory)(i => i.execute) // Epic Fail! 

Бесполезная Intermediate FactoryOf[A] была написана, чтобы представить этот вопрос. Я почти уверен, что это как-то связано с type TheType, но что это? В любом случае, это бесполезный промежуточный класс FactoryOf, который позволяет мне проверить, что type TheType совпадает с A, поэтому по этой логике я должен быть более уверенным, используя метод buildAndRun2.

ответ

1

Попробуйте

def buildAndRun3[T <: FactoryOf[_],B](factory: T)(f: factory.TheType => B): B = { 
    f(factory.make) 
} 

Я подозреваю, что TheType определяется типом FactoryOf зависит от аргумента. Вот почему фактический тип зависит от фактического экземпляра данного (зависимого от пути типа), а не только от типа.

С другой стороны, из-за buildAndRun1 компилирует TheType не определен в типе BaseFactoryOf, и он должен быть определен в другом типе T, который является потомком. Его можно было определить как нечто постоянное, например Int.

+0

Я не знал, что могу использовать выражение '' 'factory.TheType'''. Тпх – shayan

Смежные вопросы