规范中没有太多关于类型归属的信息,并且其中当然没有任何关于其目的的信息。除了“使传递可变参数起作用”之外,我还会使用类型归属做什么?下面是一些 scala REPL 的语法和使用效果。

scala> val s = "Dave"
s: java.lang.String = Dave

scala> val p = s:Object
p: java.lang.Object = Dave

scala> p.length
<console>:7: error: value length is not a member of java.lang.Object
       p.length
         ^
scala> p.getClass
res10: java.lang.Class[_ <: java.lang.Object] = class java.lang.String

scala> s.getClass
res11: java.lang.Class[_ <: java.lang.Object] = class java.lang.String

scala> p.asInstanceOf[String].length
res9: Int = 4
有帮助吗?

解决方案

类型归属就是告诉你想到了一个表达的是什么类型的编译器,从所有可能的有效类型。

一个类型是有效的,如果它尊重现有的限制,诸如方差和类型声明,它要么是所述类型中的一种的表达它适用于“”,或者有一个转换其适用于范围。

所以,java.lang.String extends java.lang.Object,因此任何String也是Object。在你的榜样,你宣布你想表达s被视为Object,而不是String。由于没有约束防止其与所期望的类型是s 的类型之一是,它的工作原理。

现在,你为什么要呢?考虑这样的:

scala> val s = "Dave"
s: java.lang.String = Dave

scala> val p = s: Object
p: java.lang.Object = Dave

scala> val ss = scala.collection.mutable.Set(s)
ss: scala.collection.mutable.Set[java.lang.String] = Set(Dave)

scala> val ps = scala.collection.mutable.Set(p)
ps: scala.collection.mutable.Set[java.lang.Object] = Set(Dave)

scala> ss += Nil
<console>:7: error: type mismatch;
 found   : scala.collection.immutable.Nil.type (with underlying type object Nil)
 required: java.lang.String
       ss += Nil
             ^

scala> ps += Nil
res3: ps.type = Set(List(), Dave)

您也按类型ascripting sss声明中的固定这一点,或者你也可以声明ss的类型来Set[AnyRef]

然而,类型声明实现同样的事情仅仅只要是将值分配给的标识符。其中一个总是可以做的,当然,如果一个人不关心与一次性标识符乱扔垃圾代码。例如,下面的不编译:

def prefixesOf(s: String) = s.foldLeft(Nil) { 
  case (head :: tail, char) => (head + char) :: head :: tail
  case (lst, char) => char.toString :: lst
}

但这:

def prefixesOf(s: String) = s.foldLeft(Nil: List[String]) { 
  case (head :: tail, char) => (head + char) :: head :: tail
  case (lst, char) => char.toString :: lst
}

是愚蠢到位Nil的在这里使用的标识符。虽然我可以只写List[String]()相反,这并不总是一个选项。考虑这一点,例如:

def firstVowel(s: String) = s.foldLeft(None: Option[Char]) { 
  case (None, char) => if ("aeiou" contains char.toLower) Some(char) else None
  case (vowel, _) => vowel
}

有关的参考,这是斯卡拉2.7规范(2009年3月15日草案)必须说关于类型归属:

Expr1 ::= ...
        | PostfixExpr Ascription

Ascription ::= ‘:’ InfixType
             | ‘:’ Annotation {Annotation}
             | ‘:’ ‘_’ ‘*’

其他提示

的一种可能性是,当网络和串行协议层次的东西,然后这样:

val x = 2 : Byte

远比

吸尘器
val x = 2.asInstanceOf[Byte]

第二种形式是还运行时转换(未由编译器处理),并可能导致一些有趣的溢出/下溢的条件。

我使用类型归属到纸盒中Scala的类型推断孔。例如,在foldLeft类型A的集合取B型和功能(B,A)=> B中用于将集合的元素折叠到初始元素的初始元素。 B型的实际值从初始元素的类型推断。由于无延伸列表[没有],用它作为初始元素会导致问题:

scala> val x = List(1,2,3,4)
x: List[Int] = List(1, 2, 3, 4)

scala> x.foldLeft(Nil)( (acc,elem) => elem::acc)
<console>:9: error: type mismatch;
 found   : List[Int]
 required: scala.collection.immutable.Nil.type
              x.foldLeft(Nil)( (acc,elem) => elem::acc)
                                                 ^

scala> x.foldLeft(Nil:List[Int])( (acc,elem) => elem::acc )
res2: List[Int] = List(4, 3, 2, 1)

另外,也可以只使用List.empty [INT]代替无:列表[INT]

scala> x.foldLeft(List.empty[Int])( (acc,elem) => elem::acc )
res3: List[Int] = List(4, 3, 2, 1)

编辑:List.empty [A]被实现为

override def empty[A]: List[A] = Nil

(源)

这实际上是零的一个更详细的形式:列表[A]

您可能会发现这个线程照明,如果一个比特卷积跟随。需要注意的重要一点是,您要添加的约束暗示的类型检查 - 它可以让你什么编译阶段是做一点更多的控制权

类型推断:我们可以跳过在源代码中显式给出某种类型的名称,称为类型推断。(尽管在某些特殊情况下需要。)

类型归属:明确某事物的类型称为类型归属。它能带来什么改变?

前任:值 x = 2 :字节

另请参阅:1.我们可以显式地为我们的函数指定返回类型

def t1 : Option[Option[String]] = Some(None)

> t1: Option[Option[String]]

声明这一点的另一种方式可能是:

def t2 = Some(None: Option[String])
> t2: Some[Option[String]]

这里我们没有给出 Option[Option[String]] 显式返回类型,编译器将其推断为 Some[Option[String]]。为什么 Some[Option[String]] 是因为我们在定义中使用了类型归属。

  1. 我们可以使用相同定义的另一种方法是:

    def t3 = Some(None)

    > t3: Some[None.type]

这次我们没有明确告诉编译器任何东西(这个 defi 也没有)。它推断我们的定义为 Some[None.type]

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top