加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么Scala允许嵌套数据结构,如List或Array

发布时间:2020-12-16 09:23:18 所属栏目:安全 来源:网络整理
导读:为什么像Scala这样的语言,使用非常强大的静态类型系统,可以允许以下结构: scala List(1,List(1,2)) res0: List[Any] = List(1,2)) 如果您使用Array替换List,同样的事情将会起作用.我学习了OCaml中的功能编程,它将在编译时拒绝相同的代码: # [1; [1;2]; 3];
为什么像Scala这样的语言,使用非常强大的静态类型系统,可以允许以下结构:

scala> List(1,List(1,2))
 res0: List[Any] = List(1,2))

如果您使用Array替换List,同样的事情将会起作用.我学习了OCaml中的功能编程,它将在编译时拒绝相同的代码:

# [1; [1;2]; 3];;
Characters 4-9:
  [1; [1;2]; 3];;
      ^^^^^
Error: This expression has type 'a list
       but an expression was expected of type int

那么为什么Scala允许这样编译?

解决方法

TL;博士

长篇小说,OCaml和Scala使用两种不同类型的系统:前者具有structural typing,后者具有nominal typing,因此它们在类型推理算法方面表现不同.

全面讨论

如果您在系统中允许使用nominal subtyping,这几乎是你得到的.

在分析列表时,Scala编译器会将类型计算为列表包含的所有类型的LUB(最小上限).在这种情况下,Int和List的LUB是Any.其他情况会有更明智的结果:

@ List(Some(1),None)
res0: List[Option[Int]] = List(Some(1),None)

一些[Int]和None的LUB是Option [Int],这通常是你期望的.如果用户失败,则对用户来说将是“奇怪的”

expected List[Some[Int]] but got List[Option[Int]]

OCaml使用structural subtyping,因此其类型系统在类型推断方面的工作方式不同.正如@gsg在评论中指出的那样,OCaml并不统一Scala类型,而是需要一个明确的上线.

在Scala中,编译器在执行类型推断时统一类型(由于名义子类型).

当然,您可以通过显式类型注释获得更好的错误:

@ val x: List[Int] = List(1,2))
Compilation Failed
Main.scala:53: type mismatch;
 found   : List[Any]
 required: List[Int]
}.apply
  ^

只要编译器使用-Ywarn-infer-any标志来推断Any – 通常是一个坏的标志,就可以得到警告.以下是Scala REPL的示例:

scala -Ywarn-infer-any
Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM,Java 1.8.0_51).
Type in expressions to have them evaluated.
Type :help for more information.

scala> List(1,2))
<console>:11: warning: a type was inferred to be `Any`; this may indicate a programming error.
       List(1,2))
            ^
res0: List[Any] = List(1,2))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读