2010-12-20 10 views
6

Mówię, mam ogólną cechę polecenia z metodą execute, która pobiera dane wejściowe i zwraca dane wyjściowe. Coś jakJak sprawić, aby następujący typ kodu był bezpieczny?

trait Input; 
trait Output; 

trait Command[I <: Input, O <: Output] { 
    def execute(input: I): O; 
} 

Potem zamierzam tworzyć różne polecenia, coś

class SampleInput extends Input 
class SampleOutput extends Output 

class SampleCommand extends Command[SampleInput, SampleOutput] { 
    def execute(input:SampleInput):SampleOutput = new SampleOutput() 
} 

Problem z tym jest mogłam stworzyć Command z SampleAInput i SampleBOutput i kompilator będzie przyjąć, że szczęśliwie . W jaki sposób wymusić, aby kompilator zakończył się niepowodzeniem z błędem niezgodności typu?

Jakoś muszę zgrupować Input i Output pod typem i przekazać ten typ, aby utworzyć polecenie . Jak mogę to zrobić?

Odpowiedz

18
trait InputOutput { 
    type Input 
    type Output 
} 

trait Command[IO <: InputOutput] { 
    def execute(input: IO#Input): IO#Output 
} 

Oto niektóre Wykorzystanie:

scala> trait SampleIO extends InputOutput {type Input = String; type Output = String} 
defined trait SampleIO 

scala> class SampleCommand extends Command[SampleIO] {def execute(input: String) = input} 
defined class SampleCommand 

scala> class SampleCommand extends Command[SampleIO] {def execute(input: String) = 1} 
<console>:13: error: type mismatch; 
found : Int(1) 
required: SampleIO#Output 
     class SampleCommand extends Command[SampleIO] {def execute(input: String) = 1} 
                       ^
+0

Doskonały! Właśnie tego szukałem. Dzięki IttayD. – sanjib

6

Ponieważ ograniczeniem jest to, że typ wejściowych i wyjściowych być taki sam, chciałbym spróbować wykonać następujące czynności:

 
trait Input[T] 
trait Output[T] 

trait Command[T] { 
    def execute[I <: Input[T], O <: Output[T]](i: I): O 
} 

Spróbujmy to z dwóch różnych typów.

 
class SampleInput extends Input[String] 
class SampleOutput extends Output[Int] 


scala> class SampleCommand extends Command[String] {     
    | def execute(input: SampleInput): SampleOutput = new SampleOutput 
    | } 
:10: error: class SampleCommand needs to be abstract, since method execute in trait Command of type [I <: Input[String],O <: Output[String]](i: I)O is not defined 
     class SampleCommand extends Command[String] { 
      ^
+0

mi się podoba, nie ma potrzeby wprowadzania pary i wyjście w tę samą cechę. – GClaramunt

0

jestem trochę późno, ale jak o tym:

object inout { 

    trait ~>[I, O] 

    trait FooInput 
    trait FooOutput 

    trait BarOutput 

    //this specifies a valid input-output combination 
    implicit object fooInOut extends ~>[FooInput,FooOutput] 

    class Command[I, O](implicit val valid: I ~> O) { 
    def execute(input: I): O; 
    } 

    class FooCommand extends Command[FooInput, FooOutput] 

    //won't compile: 
    //class FubarCommand extends Command[FooInput, BarOutput] 
} 
Powiązane problemy