2010-06-22 18 views

Odpowiedz

20

3.5.3 Słaby Zgodności w niektórych sytuacjach Scala używa bardziej ogólny potwierdzeń, relację. Typ S słabo jest zgodny z typem T, napisany S <: w T , jeśli S <: T lub zarówno S i T są prymitywne typy numeryczne i S poprzedza T w następującej kolejności.

  • Byte <: w Krótki
  • Byte <: w Charakter
  • Krótki <: w Int
  • Int <: w Długi
  • Długi <: w pływakowy
  • pływakowy <: w dwukrotnie

Słaby najmniej górna granica jest najmniej górna granica w odniesieniu do słabego zgodności.

Gdzie to jest używane? Po pierwsze, określa rodzaj if wyrażeń:

typu ekspresji warunkowej jest słaby najmniej górna granica (§3.5.3) rodzajów E2 i E3

W Scala 2.7.x byłby to typ AnyVal, najmniejszy limit związany z Int i Double. W wersji 2.8.x zapisuje się jako Double.

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

Podobnie:

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> 

Innym miejscem jest on stosowany jest w rodzaju wnioskowania:

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 

A także do prostego poszerzenia numerycznej:

poszerzenie numeryczna. Jeżeli E ma pierwotnych numeryczny słabo zgodny (§3.5.3) do przewidywanego typu jest rozszerzony oczekiwanego typu za pomocą jednego z 6,26 to konwersja 97 liczbowe metody konwersji toShort, toChar, toInt , toLong, toFloat, toDouble zdefiniowane w § 12.2.1. typ oczekiwany to prymitywny numeryczny kod typu Bajt, krótki lub Char, a wyrażenie e jest całkowitym dosłownym dopasowaniem w zakresie w zakresie tego typu, jest konwertowane na ten sam literał tego samego.

scala> 1: Double 
res10: Double = 1.0 

UPDATE

Jak zauważył Daniel, spec jest złe, o których typy mają słabą zgodność. Zapytajmy sam kompilator:

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

Według Scala lang specyfikacji 2,8:
http://www.scala-lang.org/archives/downloads/distrib/files/nightly/pdfs/ScalaReference.pdf

3.5.3 Słaby zgodności
W niektórych sytuacjach Scala wykorzystuje bardziej genral potwierdzeń, związek. Typ S słabo jest zgodny z typem T, napisanym S <: w T, jeśli S <: T lub oba S i T są prymitywnymi numerami typy i S poprzedza T w następującym porządku.
Byte <: w krótkim
Byte <: bez znaków
Krótki <: w Int
Int <: w Longa
Długie <: w Float
Float <: w Pokój
Słaby kres górny jest najmniejsza górna granica w odniesieniu do słabej zgodności.

+0

Jestem prawie pewny, że "Char" odpowiada również "Int". –

5

Aby zakończyć Sandor's answer, ta nowa funkcja w wersji 2.8 nadal jest pieczona (i naprawiana).

W this thread, Esser odkrywa przykry efekt uboczny:

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 

Wydaje się interesujące, ponieważ w sposób dorozumiany znaleźć typ wynik jest Double a wynik jest 3,0.
Jeśli Pokój jest wyraźnie podane, wynik jest 3,33 ...

W this thread, Martin Odersky dodaje (21 czerwca):

Ci odkryli poważną niezamierzony efekt uboczny słaby zasady zgodności w przeciążeniu rozdzielczości.
Problem polegał na tym, że argumenty przeciążonych metod są wymagane do słabej zgodności, podczas gdy typ wyniku był wymagany, aby silnie się dostosować.

to preferowane metody Float => Float dodawanie na Int w stosunku do metody Int => Int jeśli typ rezultacie pływaka.
Starałem się być konserwatywny w mojej zmianie na słabą zgodność, ponieważ wymagałem słabej zgodności tylko tam, gdzie było to absolutnie konieczne.
Ale wydaje się, że bycie konserwatystą spowodowało problem, na który patrzymy!

I kolejny release Scala RC;)


Potwierdzone w this thread by Martin Odersky (June 22d):

Więc nie będzie RC7 z dotychczas trzy zmiany z RC6:

  1. val x: Double = 10/3 da 3.0, a nie 3.3333333 - to był regres byłem wspomnieć
  2. [...]
  3. [...]

To wszystko. Naszym priorytetem jest teraz jak najszybsze wdrożenie 2.8, a jednocześnie unikanie naprawdę złych regresji, takich jak (1) powyżej.

Czas:

  • Będziemy czekać jeszcze jeden tydzień, aby uzyskać opinię na temat RC6.
  • Wypchniemy RC7 na początku przyszłego tygodnia.
    Jeśli nie pojawią się żadne dalsze problemy, RC7 zmieni się w 2.8 w 10-14 dni po zwolnieniu.

(tak około 12 lipca, wierzę, ale to jest moje przypuszczenie sam;))

Powiązane problemy