专栏名称: 程序员专栏
点击关注,进实战技术交流群!分享技术文章、工具资源、精选课程、视频教程、热点资讯、学习资料等。
目录
相关文章推荐
价值投资家  ·  2月7日操作公开,今天中午大盘3315.41 ... ·  18 小时前  
价值投资家  ·  2月7日操作公开,今天中午大盘3315.41 ... ·  18 小时前  
飞哥带你看市场  ·  多看少动 ·  2 天前  
飞哥带你看市场  ·  多看少动 ·  2 天前  
唐史主任司马迁  ·  传媒和计算机推票凶一点,电子反而推的含蓄。按 ... ·  3 天前  
唐史主任司马迁  ·  别怕啊,咱这把也不是2018那会儿没打过,这 ... ·  3 天前  
51好读  ›  专栏  ›  程序员专栏

Java 变得越来越像 Rust?

程序员专栏  · 公众号  ·  · 2024-03-21 18:00

正文

架构师大咖
架构师大咖,打造有价值的架构师交流平台。分享架构师干货、教程、课程、资讯。架构师大咖,每日推送。
公众号

随着编程技术的增强和复杂性的提升,许多编程语言也纷纷效仿,Java 也不例外。

另一边,尽管社区内部问题重重,但 Rust 仍逐年获得开发人员的喜爱。这背后都是有原因的:Rust 的编译器让开发人员避免了各种问题。编译器对正确性的要求让一些开发人员开始感到不安全。

我想展示两个 Rust 特性,它们是 Rust 优秀之处的一部分,然后将它们与 Java 的最新创新进行比较。

免责声明:我绝不是说这些 Rust 特性导致 Java 中出现了相应的特性。如果是 Kotlin 或 Scala 在实现这些特性方面发挥了更大的作用,我也不会感到惊讶。但是,我很高兴看到 Rust 的特性也能在(某种程度上)Java 中找到!

Immutable Data

在编程领域,Immutable Data 是指一种一旦创建就不能更改的数据结构。在 Rust 中,数据默认是不可变的。

struct User {
// struct members are immutable
name: & 'static str,
age:  i32
}

fn main() {
// user and members are immutable
let user = User { name: "Bob", age: 42 };
}

如果我们希望数据是可变的,就必须显式声明它是可变的。

fn main () {
let mut user = User { name: "Bob" , age: 42 };
user.name = "Jim" ;
}

现在,普通的 Java 对象(又称 POJO)在编写时通常默认具有可变性,而且相当冗长。

下面是它在 Java 8 中的样子:

public class User {
private String name;
private int age;

public User ( String name, int age ) {
this .name = name;
this .age = age;
}

public String getName () {
return this .name;
}

public int getAge () {
return this .age;
}

public void setName ( String name ) {
this .name = name;
}

public void setAge ( int age ) {
this .age = age;
}

public static void main ( String[] args ) {
User user = new User( "Bob" , 42 );
user.setName( "Jim" );
System. out .println(user.getName());
}

// not to mention equals(), toString() and friends!
}

不过,多亏了现代 Java,记录类简化了这一过程,并考虑到了不变性,我们的代码也就不那么冗长了。下面是启用了预览功能的有效 Java 21 代码。

record User ( String name, int age ) {}

void main () {
final var user = new User( "Bob" , 42 );
}

代数数据类型

在这段视频中,我们将看到 Rust 如何利用代数类型来帮助使无效状态无法表示,并有力地保证不会出现错误行为。

在 Rust 中,这可以通过使用枚举来实现:

enum RealCat {
Alive { is_hungry: bool },
Dead
}

fn main () {
let real_cat: RealCat = RealCat::Alive { is_hungry: true };
match real_cat {
RealCat::Alive { is_hungry } => {
if is_hungry {
println!( "The cat demands a sacrifice." );
} else {
println!( "The cat is bored." );
}
},
RealCat::Dead => println!( "Oh no!!!" )
}
}

直到最近,Java 仍无法优雅地实现这一点。不过,从 Java 21 及以后的版本开始,您可以使用包含记录的密封接口和详尽的开关语法在 Java 中优雅地实现这一功能:

RealCat.java

public sealed interface RealCat permits RealCat . Alive , RealCat . Dead {

record Alive






请到「今天看啥」查看全文