首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java 变得越来越像 Rust?

翻译 |?DeepL翻译? ? ? ?责编 | 苏宓

出品 | CSDN(ID:CSDNnews)

随着编程技术的增强和复杂性的提升,许多编程语言也纷纷效仿,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(boolean?isHungry)?implements?RealCat?{}

record?Dead()?implements?RealCat?{}

static?void?check(RealCat?realCat)?{

switch?(realCat)?{

case?Alive?aliveCat?->?{

if?(aliveCat.isHungry())?{

System.out.println("The?cat?demands?a?sacrifice.");

}?else?{

System.out.println("The?cat?is?bored.");

}

}

case?Dead?_?->?System.out.println("Oh?no!!!");

}

}

}

RealCatApplication.java

void?main()?{

final?var?hungryCat?=?new?RealCat.Alive(true);

RealCat.check(hungryCat);

}

结论

有无数理由表明 Java 永远不会成为 Rust,但我很高兴看到 Rust 的一些强大功能正在进入 Java。这将巩固 Java 作为商业世界首选编程语言之一的长期地位。由于 OpenJDK 项目致力于提高开发人员的工作效率,Java 在过去 28 年中一直占据着重要的市场份额,即使不能在未来 28 年中重新夺回重要的市场份额,也有望保持这一地位。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/ObJNoIbkksrOKtTRNVwfsN_A0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com