Java记录支持“with”语法吗?

9

Java 14 带来了记录,这是许多函数式语言中看到的重大改进:

Java:

public record Vehicle(String brand, String licensePlate) {}

ML:

type Vehicle = 
  {
    Brand : string
    LicensePlate : string
  }

在机器学习语言中,可以通过创建一个带有少量更改值的副本来“更新”记录:
let u = 
  {
    Brand = "Subaru"
    LicensePlate = "ABC-DEFG"
  }

let v =
  {
    u with 
      LicensePlate = "LMN-OPQR"
  }

// Same as: 
let v = 
  {
    Brand = u.Brand
    LicensePlate = "LMN-OPQR"
  }

Java 14 是否支持此功能?


2
转到Java 16。它们有一些不错的变化。答案是否定的。 - Thorbjørn Ravn Andersen
2
不幸的是,答案是:还没有。 - Johannes Kuhn
2
@texasbruce 不要使用Lombok。它在幕后做了非常不好的事情。 - Thorbjørn Ravn Andersen
4
这份探索性文件中描述了"马肩隆"的概念:不可变对象的功能转换 - ZhekaKozlov
2
@texasbruce 别这样做。这会让你的程序不够具备未来性。 - Thorbjørn Ravn Andersen
显示剩余9条评论
1个回答

6
很不幸,Java 不包含此功能。但是,您可以创建一个实用程序方法,接受不同的车牌值:
public static Vehicle withLicensePlate(Vehicle a, String newLicensePlate) {
    return new Vehicle(a.brand, newLicensePlate);
}

用法如下:

Vehicle a = new Vehicle("Subaru", "ABC-DEFG");
Vehicle b = Vehicle.withLicensePlate(a, "LMN-OPQR");

这将为您提供与使用“with”标签尝试的类似结果。而且,您可以将其用作更新记录的一种方式。

6
正确的声明应该是 public Vehicle(Vehicle a, String newLicensePlate) { this(a.brand, newLicensePlate); },但这种模式本身就不好。构造函数的参数类型无法表明参数是新品牌还是新车牌,而为这两个元素各自提供支持的构造函数在它们具有相同类型时根本行不通。更加清晰的方式是向记录(record)添加一个方法,如 public Vehicle withLicensePlate(String newLicensePlate) { return new Vehicle(brand, newLicensePlate); },可以像 Vehicle b = a.withLicensePlate("LMN-OPQR"); 这样使用。 - Holger
@Holger 我不太熟悉机器学习,而且根据 OP 的信息,with 模式是在不引入任何新方法的情况下期望从记录中获得的。我几乎制定了与您提议的设计类似的方案这里,但在我的(现已删除的)答案中,我无法真正满足 OP 的期望,我相信。 - Naman
@Holger的建议是使用with可以自动实现的。令人失望的是,Java不支持这一点;当一个编程语言有“记录”时,通常会假定该特性已经存在。 - sdgfsdh
2
@Naman 我知道OP要求的自动化机制目前还不存在(尚未?)。我只是回应了那个建议使用构造函数的答案,而实际上使用方法会更好。 - Holger
@Holger,以防你还没有厌倦我向你发问题(在我看来只有你能回答),这里有一个。 - Eugene
1
FYI - 我已经编写了一个库,用于生成 Java 16 记录的 "with"ers:https://github.com/Randgalt/record-builder - Randgalt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接