• Java 变得越来越像 Rust?


    随着编程技术的增强和复杂性的提升,许多编程语言也纷纷效仿,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 年中重新夺回重要的市场份额,也有望保持这一地位。

  • 相关阅读:
    Swift 学习笔记
    ServletFileUpload获取上传的多个文件和数据
    【python深度学习】——torch.min()
    SpringBoot - @ControllerAdvice注解详解
    【qemu逃逸】XCTF 华为高校挑战赛决赛-pipeline
    appium自动化测试技术
    集美大学 - 2840 - 实验3
    【Linux常用(实用)命令大全】
    自定义类型详解(上)
    模拟电路 第二章(三极管及其放大电路)【下】
  • 原文地址:https://blog.csdn.net/H_Sino/article/details/137902704