Scala中的类型归属的目的是什么? [英] What is the purpose of type ascriptions in Scala?

查看:95
本文介绍了Scala中的类型归属的目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

规范中关于类型归因的信息不多,并且关于它的用途当然也没有任何信息.除了使传递的varargs起作用"之外,我还要使用类型归属吗?以下是一些scala REPL,以了解使用它的语法和效果.

There's not much info in the spec on what type ascription is, and there certainly isn't anything in there about the purpose for it. Other than "making passing varargs work", what would I use type ascription for? Below is some scala REPL for the syntax and effects of using it.

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

推荐答案

类型描述只是告诉编译器,从所有可能的有效类型中,表达式期望什么类型.

Type ascription is just telling the compiler what type you expect out of an expression, from all possible valid types.

如果类型遵守现有约束(例如方差和类型声明),则该类型有效,并且它是该表达式应用于" is a "的类型之一,或者存在一个转换,适用范围.

A type is valid if it respects existing constraints, such as variance and type declarations, and it is either one of the types the expression it applies to "is a", or there's a conversion that applies in scope.

因此,java.lang.String extends java.lang.Object,因此任何String也是Object.在您的示例中,您声明希望将表达式s视为Object,而不是String.由于没有任何限制可以阻止这种情况,并且所需的类型是s 的类型之一,因此它可以工作.

So, java.lang.String extends java.lang.Object, therefore any String is also an Object. In your example you declared you want the expression s to be treated as an Object, not a String. Since there is no constraints preventing that and the desired type is one of the types s is a, it works.

现在,你为什么要那样?考虑一下:

Now, why would you want that? Consider this:

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)

您也可以通过在ss声明中键入s来解决此问题,或者可以将ss的类型声明为Set[AnyRef].

You could also have fixed this by type ascripting s at ss declaration, or you could have declared ss's type to be Set[AnyRef].

但是,只有在为标识符分配值时,类型声明才能实现相同的目的.当然,如果一个人不关心用一次性标识符乱扔代码,那哪一个总是可以做的.例如,以下内容不会编译:

However, type declarations achieve the same thing only as long as you are assigning a value to an identifier. Which one can always do, of course, if one doesn't care about littering the code with one-shot identifiers. For example, the following does not compile:

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](),但这并不总是一种选择.例如,考虑一下:

It would be silly to use an identifier here in place of Nil. And though I could just write List[String]() instead, that isn't always an option. Consider this, for instance:

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日草案)对类型归因的要求:

For the reference, this is what Scala 2.7 spec (march 15, 2009 draft) has to say about type ascription:

Expr1 ::= ...
        | PostfixExpr Ascription

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

这篇关于Scala中的类型归属的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆