Scala中类型归属的目的是什么?

Scala中类型归属的目的是什么?,scala,static-typing,ascription,Scala,Static Typing,Ascription,规范中没有太多关于类型归属的信息,当然也没有任何关于它的用途的信息。除了“使传递的varargs工作”,我使用类型归属还有什么用?下面是一些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 le

规范中没有太多关于类型归属的信息,当然也没有任何关于它的用途的信息。除了“使传递的varargs工作”,我使用类型归属还有什么用?下面是一些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
scala>val s=“Dave”
s:java.lang.String=Dave
scala>val p=s:Object
p:java.lang.Object=Dave
scala>p.length
:7:错误:值长度不是java.lang.Object的成员
p、 长度
^
scala>p.getClass
res10:java.lang.Class[\us.getClass]
res11:java.lang.Class[\p.asInstanceOf[String].length
res9:Int=4

类型归属只是告诉编译器,从所有可能的有效类型中,您希望从表达式中得到什么类型

如果类型尊重现有约束(如差异和类型声明),并且它是它应用于的表达式“Isa”的类型之一,或者存在适用于范围的转换,则该类型是有效的

因此,
java.lang.String扩展了java.lang.Object
,因此任何
字符串
也是一个
对象
。在您的示例中,您声明希望表达式
s
被视为一个
对象
,而不是
字符串
。因为没有任何约束阻止这一点,并且所需的类型是一种类型es
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)
但这确实:

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

在这里使用一个标识符代替<代码> nIL/COD>将是愚蠢的。尽管我可以只写<代码>列表[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
}
作为参考,以下是Scala 2.7规范(2009年3月15日草案)关于类型归属的说明:

Expr1 ::= ...
        | PostfixExpr Ascription

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

一种可能性是,当网络和串行协议级别的东西,然后:

val x = 2 : Byte
远比

val x = 2.asInstanceOf[Byte]

第二种形式也是运行时转换(不由编译器处理)并且可能会导致一些有趣的过流/欠流情况。

您可能会发现这一点很有启发性,如果后面有点复杂的话。需要注意的重要一点是,您正在向类型检查器添加约束提示-它让您对编译阶段的操作有更多的控制。

我使用类型归属来填补Sc中的漏洞ala的类型推断。例如,类型a集合上的foldLeft接受类型B的初始元素和用于将集合元素折叠到初始元素中的函数(B,a)=>B。类型B的实际值是从初始元素的类型推断出来的。因为Nil扩展了列表[Nothing],将其用作初始元素会导致问题:

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)
编辑:列表。空[A]实现为

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


这实际上是Nil:List[a]

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

类型归属:明确某事物的类型称为类型归属。 这会有什么不同

ex:val x=2:Byte

另见: 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]]
是因为我们在定义中使用了类型归属

  • 我们使用相同定义的另一种方法是:

    def t3=部分(无)

    >t3:Some[None.type]


  • 这一次,我们没有显式地告诉编译器任何事情(这个defi也没有),它将我们的定义推断为Some[None.type]

    :)我把我的问题转发到这里,这样它就会被保留下来;我选择的答案是从那条线索中选出来的,对meSorry来说是最清楚的,刚刚看到了这一点。完成了。嘿,学到了一些新东西。我做了大量的网络协议工作。很高兴知道!为什么不使用日常语法?
    val x:Byte=2
    为什么不
    x.foldLeft[列表[Int]](无)((acc,elem)=>elem::acc)
    def t1 : Option[Option[String]] = Some(None)
    
    > t1: Option[Option[String]]
    
    def t2 = Some(None: Option[String])
    > t2: Some[Option[String]]