2012-10-04 9 views
11

próbuję wykonać następujący kod:Strukturalne pisanie w Scali nie działa z Double?

def sum(e: { def *(x: Double): Double}) = e * 2.0 

Problem jest, to nie działa ze wszystkimi klasami numerycznych:

sum(20.0) 
<console>:9: error: type mismatch; 
found : Double(10.0) 
required: AnyRef{def *(x: Double): Double} 
       algo(10.0) 

sum(10) 
<console>:9: error: type mismatch; 
found : Int(10) 
required: AnyRef{def *(x: Double): Double} 
       algo(10) 

Czy jest coś złego w moim kodu?

+0

Wydaje się, że problemem jest to, że Double to typ wartości (podtyp AnyVal). A typowanie strukturalne scala wymaga instancji typu referencyjnego (AnyRef) – zvez

Odpowiedz

14

Typ konstrukcji Scala nie wymaga funkcji AnyRef.

Z pewnością poniższa deklaracja metody nie działa zgodnie z oczekiwaniami.

def sum(e: { def *(x: Double): Double }) = e * 2.0 

Powodem tego jest powyższy kod jest interpretowany jako poniższych:

def sum(e: AnyRef { def *(x: Double): Double}) = e * 2.0 

Jeśli podasz Wszelkie wyraźnie, kod działa:

scala> def sum(e: Any { def *(x: Double): Double }) = e * 2.0 
sum: (e: Any{def *(x: Double): Double})Double 

scala> sum(10.0) 
res0: Double = 20.0 
+0

Warto zauważyć, że to zachowanie jest zdefiniowane w sekcji "3.2.7 Typy złożone" [spec] (http://www.scala-lang.org/docu/ files/ScalaReference.pdf): "Typ złożony może również składać się z samego udoskonalenia' {R} "bez poprzedzających typów komponentów.Taki typ jest równoważny' AnyRef {R} '." –

+0

+1. Wow, nigdy o tym nie wiedziałem! – missingfaktor

9

Wybrana metoda sum oczekuje podtypu AnyRef podczas Double i inne typy numeryczne podtypy AnyVal. Zamiast tego należy użyć czcionki typowej Numeric.

def sum[E:Numeric](e:E) = { 
    val n = implicitly[Numeric[E]] 
    n.toDouble(e) * 2 
}