从JVM/C角度看Rust特性


Rust 是一种相对较新的(与 C 或 Java 等相比)静态类型语言。这带来了一些机遇和挑战。从头开始创建新的生态系统时,您不必保持任何向后兼容性。它可以根据其他平台的经验教训来创建,引入更彻底的变化。

今天我们来谈谈一些乍一看很有趣的 Rust 特征或特性。

没有null空!
对于很多语言来说 Null 都是一场噩梦。

在 Java 中,项目倾向于利用防御性编程实践来检查所有传入值参(如果确定它们不为空)。
在 Scala 中,作为最佳实践,不会有 null,但是由于 JVM 和与 Java 库的兼容性,它们仍然存在于语言级别。
Tony Hoarse 认为 ALGOL 中的空引入是他的“价值数十亿美元的错误”。

可能每个使用 Java 的人都至少见过一次 NullPointerException。
相反,在 Rust 中,你找不到它们。
其他语言使用 null 处理的每种情况都由 Option 枚举等处理。

默认不变性
在Java中,变量是可变的。您可以找到final到处利用该关键字的项目,试图使它们不可变,但是,它仍然不能提供可靠的保证(因为分配给给定最终变量的对象可以具有可变字段)。

在 Scala 中,可变性是一种不好的做法。case类vals 是不可变的,但如果需要,可以使用可变性。

Rust 遵循同样的方式,默认情况下所有变量都是不可变的。

为什么?我们用一句话来回答:
不可变对象总是线程安全的- 布莱恩-戈兹

如果需要可变性,可以通过使用额外的修饰符来实现

工具 - 代码格式化
Rust 工具有内置文档(Rust 书)和代码格式化工具。

在 Java 中,我认为没有任何代码格式化标准。
在 Scala 中,scalafmt 工具非常流行,但仍不是每个项目都使用它。

而在 Rust 中,它只是内置的,因此采用起来可能会容易得多。
Cargo 还包含 Clippy,它是 Rust 的一个强大插件。

并发特性
JVM 内存模型是一个神奇的地方。了解它及其工作原理可能会让你大吃一惊。使用 volatile 关键字实现并发并不容易。实际操作顺序并不那么清晰。在 C 语言中也不容易:您必须经常处理竞争条件等问题。

Rust 采用了完全不同的方法。

它引入了一些概念(这些概念以前往往为人所知,但并未在最流行的语言中使用)
生命周期、借用、不可变引用。
所有这些都可以在编译时验证你的代码是否安全。

Rust 可以防止你做一些可能导致运行时问题的事情。


依赖模式
使用 JVM 时,所有项目依赖库都放在项目 classpath 上。项目只依赖给定库的一个特定版本。当出现冲突时,会选择较新的版本。然而,这种情况可能会导致运行时问题,即找不到某些类或方法。

在 Rust 中,Cargo 可以理解语义版本控制(Semantic Versioning)。你的项目所依赖的 crates 可能依赖于同一库的不同版本。编译器会为你处理这些问题。此外,通过使用依赖重命名功能,还可以在源代码中明确使用同一库的两个不同版本。

性能特征
Java 有几种循环类型,例如传统的 for 和 foreach。我还记得以前关于foreach更慢的争论!类似的文章在 Java 8 引入 lambdas 时也出现过。

在 Rust 中,情况有些不同。
闭包和迭代器的实现不会影响运行时性能。

Rust 的目标是提供零成本的抽象,因此更高级的特性不会影响运行时,而是在编译时处理。

结论
Rust 很吸引人。它解决了 JVM 世界中经常遇到的一些问题。

与 C 或 C++ 等语言相比,它的设计选择也显示出明显的优势。它不是最简单的语言,但绝对强大。

现在,它已经在各种工具应用或系统级实现中找到了替代 C 语言的位置。
Rust 语言正在蓬勃发展,你也可以找到很多适用于它的web框架。

不过,与 Java 等语言相比,用 Rust 构建一个简单的Web应用可能更困难、更耗时。
如果你不需要它的性能,那么 Java/Scala 可能就足够了。