Scala中类型归属的目的是什么?
规范中没有太多关于类型归属的信息,当然也没有任何关于它的用途的信息。除了“使传递的varargs工作”,我使用类型归属还有什么用?下面是一些scala REPL的语法和使用效果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
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
被视为一个对象
,而不是字符串
。因为没有任何约束阻止这一点,并且所需的类型是一种类型ess
是一个,它可以工作
<>现在,你为什么要这样?考虑一下:
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]]