博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(类型归属) What is the purpose of type ascriptions in Scala?
阅读量:6834 次
发布时间:2019-06-26

本文共 3302 字,大约阅读时间需要 11 分钟。

hot3.png

Question:

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 = Davescala> val p = s:Objectp: java.lang.Object = Davescala> p.length
:7: error: value length is not a member of java.lang.Object p.length ^scala> p.getClassres10: java.lang.Class[_ <: java.lang.Object] = class java.lang.Stringscala> s.getClassres11: java.lang.Class[_ <: java.lang.Object] = class java.lang.Stringscala> p.asInstanceOf[String].lengthres9: Int = 4

 

Answer:

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

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.

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 = Davescala> val p = s: Objectp: java.lang.Object = Davescala> 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
:7: error: type mismatch; found : scala.collection.immutable.Nil.type (with underlying type object Nil) required: java.lang.String ss += Nil ^scala> ps += Nilres3: ps.type = Set(List(), Dave)

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}

But this does:

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

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}

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

Expr1 ::= ...        | PostfixExpr AscriptionAscription ::= ‘:’ InfixType             | ‘:’ Annotation {Annotation}             | ‘:’ ‘_’ ‘*’

转载于:https://my.oschina.net/u/2935389/blog/983105

你可能感兴趣的文章
c语言操作符的优先级
查看>>
Python-JS事件与面向对象操作
查看>>
IDDD 实现领域驱动设计-理解领域和子域
查看>>
Python标准库之urllib,urllib2自定义Opener
查看>>
jquery 自动完成 Autocomplete插件汇总
查看>>
jquery表单选择器
查看>>
日志插件 log4net 的使用
查看>>
小程序一:小程序的框架
查看>>
使用delphi 开发多层应用(八)客户端更新数据到kbmMW服务器
查看>>
HDU_3062 Party (2-SAT)
查看>>
dynamic_shift_reg SRL16E
查看>>
尝试用微博记录 SQL Server 2012开发者训练营笔记
查看>>
.Net中的5种事务总结
查看>>
为什么 Git 比 SVN 好
查看>>
关于Qt的MVC模型思想(转载)
查看>>
Vagrant支持Amazon AWS和Rackspace
查看>>
JNDI全攻略(二)(转)
查看>>
POJ1463:Strategic game(树形DP)
查看>>
SPOJ LCS(Longest Common Substring-后缀自动机-结点的Parent包含关系)
查看>>
Tuning 05 Sizing other SGA Structure
查看>>