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

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

问题描述

规范中没有太多关于归属地类型的信息,当然也没有任何关于其目的的信息.除了使传递可变参数工作"之外,我还会使用类型归属地做什么?下面是一些 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 扩展了 java.lang.Object,因此任何 String 也是一个 Object.在您的示例中,您声明希望将表达式 s 视为 Object,而不是 String.由于没有任何限制阻止这种情况发生,并且所需的类型是 s is a 类型之一,因此它可以工作.

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 的类型声明为 <代码>设置[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天全站免登陆