首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Scala允许嵌套数据结构,如List或Array

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

Stack Overflow用户
提问于 2015-08-20 08:52:12
回答 2查看 723关注 0票数 14

为什么像Scala这样的语言具有非常强的静态类型系统,允许使用以下结构:

代码语言:javascript
运行
复制
 scala> List(1, List(1,2))
 res0: List[Any] = List(1, List(1, 2))

如果将List替换为Array,则同样有效。我在OCaml中学习了函数式编程,它会在编译时拒绝相同的代码:

代码语言:javascript
运行
复制
# [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允许它编译呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-20 09:37:13

tl;dr

长话短说,OCaml和Scala使用了两类不同的类型系统:前者有结构分型,后者有标称打字,因此它们在类型推理算法方面表现不同。

充分讨论

如果您允许在您的类型系统中使用标称子类型,那几乎就是您所得到的。

当分析List时,Scala编译器将该类型计算为列表包含的所有类型的LUB (最小上限)。在这种情况下,IntList的LUB是Any。其他案件将产生更明智的结果:

代码语言:javascript
运行
复制
@ List(Some(1), None)
res0: List[Option[Int]] = List(Some(1), None)

Some[Int]None的LUB是Option[Int],这通常是您所期望的。如果这样做失败了,用户将感到“奇怪”:

代码语言:javascript
运行
复制
expected List[Some[Int]] but got List[Option[Int]]

OCaml使用结构亚型,因此其类型系统在类型推断方面的工作方式不同。正如@gsg在评论中指出的那样,OCaml没有特别统一像Scala这样的类型,而是需要一个显式的向上转换。

在Scala中,编译器在执行类型推断时统一类型(由于标称子类型)。

当然,使用显式类型注释可以获得更好的错误:

代码语言:javascript
运行
复制
@ val x: List[Int] = List(1, List(1, 2))
Compilation Failed
Main.scala:53: type mismatch;
 found   : List[Any]
 required: List[Int]
}.apply
  ^

当编译器使用Any标志推断-Ywarn-infer-any时(这通常是一个不好的标志),您就可以得到警告。下面是scala的一个示例:

代码语言:javascript
运行
复制
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, List(1, 2))
<console>:11: warning: a type was inferred to be `Any`; this may indicate a programming error.
       List(1, List(1, 2))
            ^
res0: List[Any] = List(1, List(1, 2))
票数 19
EN

Stack Overflow用户

发布于 2015-08-20 09:36:26

因为Scala允许隐式子类型,所以它能够推断这种内容混合的表达式的“正确”类型。Scala正确地推断您的列表是List[Any]类型的,这意味着它中的任何事情都可能发生。

因为Ocaml不支持隐式子类型,所以没有显式的下向转换;它不能自动扩展混合列表的类型。

最常见的情况是,如果您以AnyAnyRef类型结束,那么您已经搞砸了一些东西,但在某些情况下,它也可能是正确的。这取决于程序员是否需要更严格的类型。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32113732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档