右边的Scala类型注释?

右边的Scala类型注释?,scala,Scala,在scala中,如果我有如下声明: val i: Float = 5 这和这一行一样吗 val i = 5: Float ? 最近我遇到了一个表达式,它的右侧有这样的类型注释,我想知道它的用法是什么,因为我在规范中找不到它。此语法用于将类型分配给表达式(而val I:Float=5将类型分配给术语)。当你用一个更大的表达式的一部分来做时,它会产生不同 scala> implicit class WeirdFloat(f: Float) { | def +(ff: Flo

在scala中,如果我有如下声明:

val i: Float = 5
这和这一行一样吗

val i = 5: Float 
?


最近我遇到了一个表达式,它的右侧有这样的类型注释,我想知道它的用法是什么,因为我在规范中找不到它。

此语法用于将类型分配给表达式(而
val I:Float=5
将类型分配给术语)。当你用一个更大的表达式的一部分来做时,它会产生不同

scala> implicit class WeirdFloat(f: Float) {
     |   def +(ff: Float) = new WeirdFloat(f + ff * 2)
     |   override def toString = s"$f"
     | }
defined class WeirdFloat

scala> val i: WeirdFloat = 5 + 7
i: WeirdFloat = 12.0

scala> val i = (5: WeirdFloat) + 7
i: WeirdFloat = 19.0

我认为唯一的区别是,
I
的类型是(由编译器)从第二个示例中的值推断出来的,而在第一个示例中,您是在明确说明
I
的类型

本研究鼓励尽可能使用推理类型。然而,当您使用ascription(一种编译时向上转换)时,使用类型跟随值的语法是一种方法

scala> val s = "Jane"
s: String = Jane

scala> val p = s: Object
p: Object = Jane

这被称为类型归属,其目的是在可能有多个选项可用时消除类型的歧义

一个典型的例子是褶皱:

val l = 1 to 5
val stringyfied = l.foldLeft(Nil)((list, elem) => elem.toString :: list)
在这种情况下,
Nil
的类型是什么?如果您尝试该示例,编译器将发出一个错误:

error: type mismatch;
found   : List[String]
required: scala.collection.immutable.Nil.type
通过使用类型归属,我们可以让编译器知道特定的类型:

val stringyfied = l.foldLeft(Nil:List[String])((list, elem) => elem.toString :: list)
// stringyfied: List[String] = List(5, 4, 3, 2, 1)
另一个常见用法是将集合视为vararg,如中所示:

def varargs(a:Int*) = a.sum
// common use:
varargs(1,2,3,4,5) //15

// now we have a collection of elements: 
val intlist = 1 to 5
// we cannot call varagrs with a list
varargs(intlist)
> found   : List[Int]
> required: Int

// then using type ascription:
varargs(intlist: _*)

据我所知,除了表达式代数的规范之外,没有太多关于类型归属的具体文档

我假设在第一种情况下,您将一个值定义为Float。在第二种情况下,将浮点值5赋给值i。一个很好的例子是,如果您尝试将5:Float转换为您自己的自定义类型。因此,您将处于必须定义impilict converter等的情况。在这两种情况下,您都会得到一个值为5.0的浮点变量。至少在这个例子中,它们是平等的,与背景无关。