除了类型系统之外,是什么让 Scala 成为如此出色的语言?我读到的几乎所有关于该语言的内容都将“强类型”作为使用 Scala 的一个重要原因,但必须不止于此。还有哪些其他引人注目和/或很酷的语言特性使 Scala 成为真正有用的工具?
14 回答
以下是一些让我更喜欢 Scala 的东西(比方说,通常的 Java):
a) 类型推断。Java的做法:
Map<Something, List<SomethingElse>> list = new HashMap<Something, List<SomethingElse>>()
..与Scala相比相当冗长。如果您提供这些列表之一,编译器应该能够弄清楚。
b) 一阶函数。同样,这个功能可以用类来模拟,但它很丑。
map
c) 具有和的集合fold
。这两个与 (b) 相关联,而且这两个也是我每次必须编写 Java 时都希望得到的东西。
d) 模式匹配和案例类。
e) 方差,这意味着如果S extends T
,那么List[S] extends List[T]
也是如此。
再加上一些静态类型的好处,我很快就被这门语言卖掉了。
这是一堆语言中最好的部分的混搭,有什么不值得喜欢的:
- Ruby 的简洁语法
- Java的性能
- Erlang 的演员支持
- 闭包/块
- 地图和数组的便捷简写
Scala 经常因具有闭包和隐式而广为人知。这并不奇怪,因为缺少闭包和显式类型可能是 Java 样板的两个最大来源!
但是,一旦您对其进行更深入的研究,它就会远远超出 Java-without-the-annoying bits,也许 Scala 的最大优势不是一个特定的命名功能,而是它在统一其他答案中提到的所有功能方面有多成功.
后功能
比如面向对象和函数式编程的结合:因为函数是对象,Scala能够让Maps实现Function接口,所以当你使用map来查找一个值时,它在语法上与使用函数计算一个没有区别价值。如此完美地统一了这些范式,Scala 确实是一种后函数式语言。
或运算符重载,这是通过实际上没有运算符来实现的,它们只是中缀表示法中使用的方法。所以1 + 2
只是+
在一个整数上调用该方法。如果该方法被命名plus
,那么您将使用它,因为1 plus 2
它与1.plus(2)
. 由于另一种功能组合,这成为可能;Scala 中的一切都是对象,没有原语,所以整数可以有方法。
其他功能融合
还提到了类型类,它是通过更高种类的类型、单例对象和隐式的组合来实现的。
其他可以很好地协同工作的特性是案例类和模式匹配,允许您轻松构建和解构代数数据类型,而无需手动编写 Java 所需的所有繁琐的相等、哈希码、构造函数和 getter/setter 逻辑。
默认情况下指定不变性、提供惰性值和提供一流的函数都结合在一起,为您提供了一种非常适合构建高效函数式数据结构的语言。
清单还在继续,但我已经使用 Scala 超过 3 年了,我几乎每天都对一切都可以很好地协同工作感到惊讶。
高效和多功能
Scala 也是一种小型语言,其规范(令人惊讶!)只需要大约是 Java 的 1/3 大小。这部分是因为 Java 在 Scala 简化的规范中有很多特殊情况,部分是因为删除了原语和运算符等特性,部分是因为许多功能已从语言转移到库中。
这样做的好处是,Scala 库作者可用的所有技术也可供任何 Scala 用户使用,这使其成为定义您自己的控制流结构和构建 DSL 的绝佳语言。这已经在像 Akka 这样的项目中发挥了很大的作用 - 一个 3rd-party Actor 框架。
深的
最后,它扩展了所有的编程风格。
运行时解释器(称为 REPL)允许您在交互式会话中非常快速地探索想法,并且 Scala 文件也可以作为脚本运行而无需显式编译。当与类型推断相结合时,这给 Scala 一种动态语言的感觉,例如 Ruby、Perl 或 bash 脚本。
另一方面,特征、类、对象和自类型允许您构建基于不同组件并使用依赖注入的完整企业系统,而无需第三方工具。Scala 还与 Java 库的集成水平几乎与本机 Java 相当,并且通过在 JVM 上运行可以利用该平台提供的所有速度优势,并且可以完美地用于诸如 tomcat 之类的容器中,或者操作系统吉。
我是 Scala 新手,但我的印象是:
真正好的 JVM 集成将是驱动因素。JRuby 可以调用 java,java 可以调用 JRuby 代码,但它是显式调用另一种语言,而不是 Scala-Java 的干净集成。因此,您可以使用 Java 库,甚至可以在同一个项目中混合搭配。
当我意识到驱动下一个伟大语言的东西是简单的并发时,我开始关注 scala。从性能的角度来看,JVM 具有良好的并发性。我敢肯定有人会说 Erlang 更好,但 Scala 实际上是普通程序员可以使用的。
Java 失败的地方在于它非常冗长。创建和传递 Functor 需要太多的字符。Scala 允许将函数作为参数传递。
在 Java 中无法创建联合类型,或将接口应用于现有类。这些在 Scala 中都很容易。
静态类型通常会带来冗长的巨大损失。Scala 消除了这个缺点,同时仍然提供了静态类型的优点,即编译时类型检查,它使编辑器中的代码辅助更容易。
扩展语言的能力。这是让 Lisp 持续数十年的原因,也让 Ruby on Rails 成为可能。
不久:
- 您可以获得 Java 库的强大功能和平台独立性,但没有样板和冗长。
- 您将获得 Ruby 的简单性和生产力,但具有静态类型和编译的字节码。
- 您可以获得 Haskell 的功能优势和并发支持,但没有完全的范式转换和面向对象的好处。
我发现它的所有宏伟功能特别有吸引力,其中包括:
- 大多数需要加载 Java 中的样板代码的面向对象设计模式都得到原生支持,例如 Singleton(通过对象)、Adapter、Decorator(通过特征和隐式)、Visitor(通过模式匹配)、策略(通过闭包)等.
- 您可以非常简洁地定义您的领域模型和 DSL,然后您可以使用必要的功能(通知、关联处理;解析、序列化)来扩展它们,而无需代码生成或框架。
- 最后,与支持良好的 Java 平台具有完全的互操作性。您可以在两个方向上混合使用 Java 和 Scala。在经历了 Java 使代码难以维护的烦恼之后,切换到 Scala 并没有太多的惩罚和兼容性问题。
The great features of Scala has already been mentioned. One thing that shines through past all features though, is how tastefully everything is integrated.
Scala manages to be one of the most powerful language around without having a feeling of having bolted on features in haste. Neither are the language an academic exercise in proving a point. Innovation and really advanced concepts are brought in to the language with uncanny practicality and elegance.
In short: Martin Odersky is a pure design genius. That is what's so great about Scala!
据说让 Scala 代码在多个处理器上并发运行是非常容易的。
控制流的表现力。例如,拥有需要以某种方式处理的数据集合是很常见的。这可能是一个交易列表,其中的处理涉及按某些属性(投资工具的货币)分组,然后进行求和(可能获得每种货币的总数)。
在 Java 中,这涉及分离出一段代码来进行分组(几行 for 循环),然后是另一段代码来进行求和(另一个 for 循环)。在 Scala 中,这种类型的事情通常可以在一行代码中使用函数式编程然后折叠来实现,这非常富有表现力地读取 l-to-r。
当然,这只是 Java 上的函数式语言的一个论据。
我想添加多范式(OO 和 FP)性质,让 Scala 比其他语言更具优势
每天编写 Java 代码你会变得越来越痛苦,每天编写 Scala 代码你会变得更快乐。
这里有一些关于函数式语言吸引力的相当深入的解释。
如果我们放弃功能讨论并谈论风格,我会说这是编码的管道风格。您从某个对象或集合开始,键入点和属性或点和转换,然后执行此操作,直到形成所需的结果。通过这种方式,很容易编写一个易于阅读的转换链。一定程度上的特征也将允许您应用相同的方法来构造类型。