为什么Scala允许嵌套数据结构,如List或Array
为什么像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)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |