2010-06-22 10 views

risposta

20

3.5.3 Conformità debole in alcune situazioni Scala utilizza un più generale conformità relazione. Un tipo S debolmente conforme a un tipo T, S scritta <: w T , se S <: T o entrambi S e T sono tipi di numero primitivi e S precede T nel seguente ordine.

  • Byte <: w Breve
  • Byte <: w carattere
  • Breve <: w Int
  • Int <: w lungo
  • lungo 01.238.703,954 mila: w Float
  • Float <: w doppia

Una debole estremo superiore è un limite almeno superiore rispetto alla debole conformità.

Dove viene utilizzato? Per prima cosa, si determina il tipo di if espressioni:

Il tipo dell'espressione condizionale è debole estremo superiore (§3.5.3) dei tipi di e2 e e3

In Scala 2.7.x, questo sarebbe di tipo AnyVal, il limite minimo di Int e Double. In 2.8.x, viene impostato come Double.

scala> if (true) 1 else 1d 
res0: Double = 1.0 

Analogamente:

scala> try { 1 } catch { case _ => 1.0 } 
res2: Double = 1.0 

scala> (new {}: Any) match { case 1 => 1; case _ => 1.0 } 
res6: Double = 1.0 

scala> def pf[R](pf: PartialFunction[Any, R]): PartialFunction[Any, R] = pf 
pf: [R](pf: PartialFunction[Any,R])PartialFunction[Any,R] 

scala> pf { case 1 => 1; case _ => 1d } 
res4: PartialFunction[Any,Double] = <function1> 

altro luogo esso viene utilizzato in inferenza:

scala> def foo[A](a1: A, a2: A): A = a1 
foo: [A](a1: A,a2: A)A 

scala> foo(1, 1d) 
res8: Double = 1.0 

scala> def foos[A](as: A*): A = as.head 
foos: [A](as: A*)A 

scala> foos(1, 1d) 
res9: Double = 1.0 

Ed anche per semplice ampliamento numerico:

Widening numerico. Se e ha una primitiva tipo numero conforme debolmente (§3.5.3) per il tipo previsto, è allargato al tipo previsto utilizzando uno dei 6,26 Conversioni implicite 97 metodi di conversione numerica toShort, tochar, Toint , toLong, toFloat, toDouble definito in §12.2.1. tipo previsto è un tipo numerico primitivo Byte, Short o Char e l'espressione e è un adattamento letterale intero nell'intervallo di quel tipo, viene convertito nello stesso valore letterale in quel tipo.

scala> 1: Double 
res10: Double = 1.0 

UPDATE

Come sottolineato da Daniel, la specifica è sbagliato su quali tipi hanno la conformità debole. Chiediamo al compilatore stesso:

scala> :power 
** Power User mode enabled - BEEP BOOP  ** 
** scala.tools.nsc._ has been imported  ** 
** New vals! Try repl, global, power  ** 
** New cmds! :help to discover them   ** 
** New defs! Type power.<tab> to reveal  ** 

scala> settings.maxPrintString = 10000 


scala> import global.definitions._ 
import global.definitions._ 

scala> (for{c1 <- ScalaValueClasses; 
     c2 <- ScalaValueClasses 
     isNSC = isNumericSubClass(c1, c2) 
     if isNSC 
    } yield ("isNumericSubClass (%s, %s) = %b" format (c1, c2, isNSC))).mkString("\n") 


res5: String = 
isNumericSubClass (class Byte, class Byte) = true 
isNumericSubClass (class Byte, class Short) = true 
isNumericSubClass (class Byte, class Int) = true 
isNumericSubClass (class Byte, class Long) = true 
isNumericSubClass (class Byte, class Float) = true 
isNumericSubClass (class Byte, class Double) = true 
isNumericSubClass (class Short, class Short) = true 
isNumericSubClass (class Short, class Int) = true 
isNumericSubClass (class Short, class Long) = true 
isNumericSubClass (class Short, class Float) = true 
isNumericSubClass (class Short, class Double) = true 
isNumericSubClass (class Int, class Int) = true 
isNumericSubClass (class Int, class Long) = true 
isNumericSubClass (class Int, class Float) = true 
isNumericSubClass (class Int, class Double) = true 
isNumericSubClass (class Long, class Long) = true 
isNumericSubClass (class Long, class Float) = true 
isNumericSubClass (class Long, class Double) = true 
isNumericSubClass (class Char, class Int) = true 
isNumericSubClass (class Char, class Long) = true 
isNumericSubClass (class Char, class Char) = true 
isNumericSubClass (class Char, class Float) = true 
isNumericSubClass (class Char, class Double) = true 
isNumericSubClass (class Float, class Float) = true 
isNumericSubClass (class Float, class Double) = true 
isNumericSubClass (class Double, class Double) = true 
+1

nota bene: https://lampsvn.epfl.ch/trac/scala/ticket/3594 – retronym

4

Secondo Scala Lang spec 2.8:
http://www.scala-lang.org/archives/downloads/distrib/files/nightly/pdfs/ScalaReference.pdf

3.5.3 Debole Conformance
In alcune situazioni Scala usa un rapporto di conformità più Genral. Un tipo S debolmente è conforme a un tipo T, scritto S <: w T, se S <: T o entrambi S e T sono numeri primitivi tipi e S precede T nel seguente ordine.
Byte <: w Breve
Byte <: w carattere
Breve <: w Int
Int <: w lungo
lungo <: w Float
Float <: w doppio
Un debole estremo superiore è un minimo superiore rispetto alla debole conformità.

+0

Sono quasi sicuro che 'Char' è conforme anche a' Int'. –

5

Per completare Sandor's answer, quella nuova funzione in 2.8 è ancora in fase di cottura (e fissa).

In this thread, Esser scopre un brutto effetto collaterale:

scala> val a= 10 
a: Int = 10 

scala> val b= 3 
b: Int = 3 

scala> if (b!=0) a/b else Double.NaN 
res0: Double = 3.0 

scala> def div1(a: Int, b: Int) = if (b!=0) a/b else Double.NaN 
div1: (a: Int,b: Int)Double 

scala> def div2(a: Int, b: Int): Double = if (b!=0) a/b else Double.NaN 
div2: (a: Int,b: Int)Double 

scala> div1(10,3) 
res1: Double = 3.0 

scala> div2(10,3) 
res2: Double = 3.3333333333333335 

sembra interessante, in quanto il tipo di risultato implicitamente trovato è Double e il risultato è 3,0.
Se doppio è esplicitamente dato, il risultato è 3.33 ...

In this thread, Martin Odersky aggiunge (21 giugno):

voi hanno scoperto una seria involontario effetto collaterale dei deboli regole di conformità nella risoluzione di sovraccarico.
Il problema era che gli argomenti dei metodi sovraccaricati sono richiesti per conformarsi debolmente, mentre il tipo di risultato era richiesto per conformarsi con forza.

Questo favorito il metodo Float => Float inoltre su un Int rispetto al metodo Int => Int se il tipo risultato era galleggiante.
Stavo cercando di essere prudente nel mio passaggio a una debole conformità, in quanto richiedevo una debole conformità solo dove sembrava assolutamente necessario.
Ma ora sembra che essere prudenti abbia causato il problema che stiamo guardando!

E ancora un altro rilascio Scala RC;)


confermata in this thread by Martin Odersky (June 22d):

Quindi ci sarà un RC7 con finora tre cambiamenti rispetto RC6:

  1. val x: Double = 10/3 darà 3.0, non 3.3333333 - che era la regressione accennavo
  2. [...]
  3. [...]

Questo è tutto. Le nostre priorità ora sono di distribuirle il più rapidamente possibile e allo stesso tempo evitare regressioni davvero negative come (1) sopra.

Timeline:

  • Vi aspettiamo una settimana in più per ottenere un feedback sulla RC6.
  • Spegneremo RC7 all'inizio della prossima settimana.
    Se non si verificano ulteriori problemi RC7 si trasformerebbe quindi in 2,8 finale 10-14 giorni dopo il rilascio.

(quindi intorno al 12 luglio, credo, ma questo è solo mia congettura;))

Problemi correlati