2010-06-22 73 views

回答

20

3.5.3弱一致性在某些情况下斯卡拉采用了更一般的 一致性关系。类型S弱 符合一类型T,s要写的<:瓦特Ť ,若S <:T或两者S和T是 原始号码类型和S中的以下顺序先 吨。

  • 字节<:瓦特
  • 字节<:瓦特
  • 短<:瓦特诠释
  • 诠释<:瓦特
  • 龙<:瓦特浮法
  • 浮法<:瓦特

弱最小上界是 最小上界关于弱 一致性。

它在哪里使用?一方面,它确定的if表达式类型:

类型条件表达式 的是弱最小上界(§3.5.3)的种类E2和E3的

在Scala 2.7.x中,这将是类型AnyVal,这是IntDouble的最小上限。在2.8.x中,它的类型为Double

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

同理:

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> 

它使用的另一个地方是在类型推断:

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 

,也为简单的数字加宽:

数字扩大。如果E具有弱符合一个原始 号码类型 (§3.5.3)到预期的类型,它是 加宽到使用 6.26隐式转换的一个 97种数字转换方法toShort,toChar, toInt预期的类型,toLong,toFloat,toDouble 在§12.2.1中定义。预期类型为基本数字类型Byte,Short或 Char,并且表达式e是 整型立体适合该类型的范围 ,它将转换为该类型中相同的文字 。

scala> 1: Double 
res10: Double = 1.0 

UPDATE

正如丹尼尔指出,该规范是错误的哪些类型有弱一致性。让我们问编译器本身:

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 2010-06-23 21:34:19

4

根据斯卡拉郎规格2.8:
http://www.scala-lang.org/archives/downloads/distrib/files/nightly/pdfs/ScalaReference.pdf

3.5.3弱一致性
在某些情况下斯卡拉采用了更符合GENRAL关系。 S型微弱 符合类型T,写成S <:w T,如果S <:T或S和T两者都是原始编号 类型并且S按照以下顺序在T之前。
字节<:W短
字节<:W字
短<:W诠释
诠释<:W龙
龙<:W浮动
浮动<:W双
弱至少上限是关于弱一致性的最小上限。

+0

我很确定'Char'符合'Int'。 – 2010-06-22 16:03:26

5

要完成Sandor's answer,2.8中的新功能仍在烘焙(并修复)。

this thread,Esser的揭示一个讨厌的副作用:

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 

似乎有趣,因为隐发现结果类型为Double,结果是3.0。
如果双被明确给出,结果是3.33 ...

this thread,马丁Odersky的增加(6月21日):

你已经发现的薄弱严重意想不到的副作用一致性规则在重载分辨率。
问题是重载方法的参数需要很弱地符合,而结果类型需要强烈地符合。

如果结果类型为Float,则该方法在方法的Int方法上支持Float => Float方法。
我一直试图保守,因为我只是在看起来绝对必要的时候需要很弱的一致性。
但是,现在看来保守造成了我们正在考虑的问题!

而另一个Scala的RC版本)


证实this thread by Martin Odersky (June 22d)

所以会有来自RC6至今三只改一RC7:

  1. val x: Double = 10/3会给3.0,而不是3.3333333 - 这是我提的回归
  2. [...]
  3. [...]

就是这样。我们现在的重点是尽快推出2.8,同时避免像上面(1)那样的糟糕的回归。

时间轴:

  • 我们将等待一个星期获得的RC6反馈。
  • 我们将在下周初推出RC7。
    如果没有进一步的问题出现,那么RC7在发布后的10-14天内会变成2.8。

(使周围7月12日,我相信,但这种猜测是我一个人;))