2012-02-07 16 views
17

uczę Scala i nie może zrozumieć, dlaczego:Zwraca typ w przypadku wyrażenie

def signum(arg: Int) = { 
    if(arg > 0) 1 
    else if(arg < 0) -1 
    else 0 
} 

Has Int jako typ zwracany signum (arg: Int): Int

Ale

def signum(arg: Int) = { 
    if(arg > 0) 1 
    else if(arg < 0) -1 
    else if(arg == 0) 0 
} 

Has AnyValsignum (arg: Int): AnyVal

+0

(co prawda nie jest łatwe do pełnotekstowego wyszukiwania dla: http://stackoverflow.com/questions/4038741/why-does-this-scala-line-return-a -unit –

Odpowiedz

18

W przypadku braku wyraźnego else Scala przyjmuje, że:

else() 

przypadku () jest wartość Unit. Jest to wartość zwrócona przez println lub przypisanie do var, na przykład.

Można to łatwo sprawdzić:

scala> val x = if (false) 1 
x: AnyVal =() 

scala> x.isInstanceOf[Unit] 
res3: Boolean = true 
23

Zdarza się, ponieważ w drugim c ase nie określono części końcowej else. W tym przypadku typem zwrotu tego brakującego odgałęzienia będzie Unit. Tak więc kompilator Scala podaje AnyVal jako wspólny rodzic Int i Unit.

można spróbować dodać wyraźny typ zwracany do podpisu funkcji:

def signum(arg: Int): Int = ... 

To nie będzie skompilować z następującym błędem:

found : Unit 
required: Int 
    else if(arg == 0) 0 
     ^
one error found 

więc kompilator mówi, że typ wynik ostatniego if jest w rzeczywistości Unit, a nie Int.

+9

Dodanie adnotacji typu do wszystkich publicznych członków jest bardzo dobrym pomysłem, po pierwsze zapobiega takim błędom, a po drugie jest rodzajem dokumentacji, po trzecie, czasami chcesz zwrócić pewien typ (ogólny), ale kompilator wywnioskuje najbardziej konkretny, np. chcesz _Seq_ zamiast _List_. –

Powiązane problemy