2010-06-22 14 views

Respuesta

20

3.5.3 Conformidad débil en algunas situaciones Scala utiliza un relación más general de conformidad. Un tipo S débilmente ajusta a un tipo T, S escrito <: w T , si S <: T o ambos S y T son tipos de números primitivos y S precede T en el siguiente pedido.

  • Byte <: w corto
  • Byte <: w Carácter
  • corto <: w Int
  • Int <: w largo
  • largo <: w Float
  • Float <: w Doble

Un débil extremo superior es una cota menos superior con respecto a débil conformidad.

Cuando se utiliza esta? Por un lado, se determina el tipo de if expresiones:

El tipo de la expresión condicional es la débil extremo superior (§3.5.3) de los tipos de e2 y e3

en Scala 2.7.x, esto sería por tipo de AnyVal, el menos uppper límite de Int y Double. En 2.8.x, escribe como Double.

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

mismo modo:

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> 

Otro lugar que se utiliza es en la inferencia de tipos:

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 

Y también para la ampliación numérica sencilla:

Ampliación numérico. Si E tiene un primitivo tipo número que se ajusta débilmente (§3.5.3) para el tipo esperado, es ampliado para el tipo esperado usando uno de los 6,26 conversiones implícitas 97 métodos de conversión numéricos toShort, Tochar, Toint , a Largo, a Flotar, a Doble definido en §12.2.1. tipo esperado es primitivo tipo numérico Byte, Corto o Char, y la expresión e es un literal entero que se ajusta en el rango de ese tipo, se convierte al mismo literal en ese tipo.

scala> 1: Double 
res10: Double = 1.0 

ACTUALIZACIÓN

Como ha señalado Daniel, la especificación está mal acerca de los tipos tienen la conformidad débil. Preguntémosle al compilador:

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

Según Scala lang especificación 2.8:
http://www.scala-lang.org/archives/downloads/distrib/files/nightly/pdfs/ScalaReference.pdf

3.5.3 Débil Conformidad
En algunas situaciones Scala utiliza una relación más genral conformidad. Un tipo S débilmente se ajusta a un tipo T, escrito S <: w T, si S <: T o S y T son los tipos primitivos y S precede a T en el siguiente orden.
Byte <: w Corto
Byte <: w Carácter
corto <: w Int
Int <: w largo
largo <: w flotador
flotador <: w doble
Un débil extremo superior es un límite superior mínimo con respecto a la conformidad débil.

+0

Estoy bastante seguro de que 'Char' se ajusta a 'Int' también. –

5

Para completar Sandor's answer, esa nueva característica en 2.8 aún se está horneando (y arreglando).

En this thread, Esser descubre un desagradable efecto secundario:

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 

Parece interesante, porque el tipo de resultado es implícitamente encontrado Double y el resultado es 3.0.
Si no se da explícitamente doble, el resultado es 3,33 ...

En this thread, Martin agrega Odersky (21 de junio):

que han descubierto un grave efecto secundario no deseado de los débiles reglas de conformidad en la resolución de sobrecarga.
El problema era que los argumentos de los métodos sobrecargados se requieren para ajustarse débilmente, mientras que el tipo de resultado era necesario para ajustarse con fuerza.

Esto favoreció el método Float => Float Además en una Int sobre el método Int => Int si el tipo de resultado fue Float.
Estaba tratando de ser conservador en mi cambio a la conformidad débil en el sentido de que requería una conformidad débil solo donde parecía absolutamente necesario.
¡Pero ahora parece que ser conservador ha causado el problema que estamos viendo!

Y sin embargo, otra versión Scala RC;)


confirmado en this thread by Martin Odersky (June 22d):

Así habrá un RC7 con hasta el momento tres cambios de RC6:

  1. val x: Double = 10/3 dará 3.0, no 3.3333333 - que era la regresión que estaba mencionando
  2. [...]
  3. [...]

Eso es todo. Nuestras prioridades ahora son desplegar 2.8 tan rápido como podamos, y al mismo tiempo evitar regresiones realmente malas como (1) arriba.

Cronología:

  • Vamos a esperar una semana más para obtener retroalimentación sobre RC6.
  • Expulsaremos RC7 a principios de la próxima semana.
    Si no aparecen más problemas, RC7 se convertirá en 2.8 final 10-14 días después de su lanzamiento.

(lo que alrededor de 12 de julio creo, pero esta suposición es sólo mía;))

Cuestiones relacionadas