4

【译文】Java 正在变得越来越像 Rust,而我正是为此而来!

 6 months ago
source link: https://www.techug.com/post/java-is-becoming-more-like-rust/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

随着编程技术的提升和复杂性的普及,许多编程语言也紧随其后。Java 也不例外。

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

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

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

不可变数据

在 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,record 类简化了这一过程,并考虑到了不变性,我们的代码也就不那么冗长了。下面是启用了预览功能的有效 Java 21 代码。

record User(String name, int age) {}  
  
void main() {  
    final var user = new User("Bob", 42);
}  

代数数据类型

这段 YouTube 视频中,我们将看到 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 及以后的版本开始,您可以使用包含记录的 sealed 接口和详尽的switch 语法在 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 年中重新夺回重要的市场份额,也有望保持这一地位。

本文文字及图片出自 Java is becoming more like Rust, and I am here for it!

O1CN01ked1911OQdogoVIoX_!!2768491700.jpg_640x640q80_.webp

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK