Java中的用户定义字词?

116 阅读3分钟

Java有一些用于创建数值的字面符号,但如果我们有更多的字面符号,那不是很好吗?

当前的字词

这些是我们今天可以在Java中写的一些字面符号

  • 整数 -123,12s,1234L,0xB8E817,0770b1011_1010
  • 浮点 -45.6f,56.7d7.656e6
  • 字符串 -"Hello world"
  • char -'a'
  • boolean -truefalse
  • 空------。null

Amber项目也在考虑增加多行和/或原始字符串字元。

但是还有许多其他的数据类型也会从字面意义中受益,比如日期、重构词和URIs。

用户定义的字面符号

在我理想的未来,我希望看到Java扩展到支持某种形式的用户定义的字面符号。 这将允许类的作者提供一种机制,将一串字符转换为该类的实例。 使用一种可能的语法(使用反斜线),看到一些例子可能更清楚。

 Currency currency = `GBP`;
 LocalDate date = `2019-03-29`;
 Pattern pattern = `strata\.\w+`;
 URI uri = `https://blog.joda.org/`;

将需要一些语义特征。

  • 类型推理
  • 原始处理
  • 在编译时进行验证
类型推断

类型推断当然是字面意义的一个关键方面。 它必须以类似于现有字面意义的方式工作,但要进行调整以处理新的var 关键字。即这两者将是等价的。

 LocalDate date = `2019-03-29`;
 var date = LocalDate`2019-03-29`;

类型推理也将与方法一起工作(如果有歧义的话,会出现编译错误)。

 boolean inferior = isShortMonth(`2019-04-12`);

 public boolean isShortMonth(LocalDate date) { return date.lengthOfMonth() < 31; }

原始处理

对字面的处理不应受到Java转义机制的限制。 用户定义的字面需要访问原始字符串。 注意,这对regex特别有用,但对Windows上的文件也很有用。

 // user-defined literals
 var pattern = Pattern`strata\.\w+`;
 // today
 var pattern = Pattern.compile("strata\\.\\w+");

今天,``需要转义,使得重词难以阅读。

显然,解析原始字词的问题是没有转义机制。 但是用户定义字词的用例往往有限制性的格式,例如,一个日期不包含随机字符。 因此,尽管可能有边缘情况,这将是一个问题,但它们将断然是边缘情况。

在编译时进行验证

字面符号的一个关键特征是它们在编译时被验证。 如果一个整数字面符号的值大于允许的最大整数(2^31),你就不能用它来创建一个int

用户定义的字面意义也需要在编译时进行解析和验证。 因此这段代码不会被编译。

 LocalDate date = `2019-02-31`;

大多数受益于字面意义的类型只接受特定的输入格式,因此能够在编译时检查这一点将是有益的。

这将如何实现?

我相信有多种方法可以实现。 我不打算选择一种方法,因为最终控制JVM和语言的人更有资格决定。 不过很明显,需要在用户类上有某种形式的工厂方法来执行解析,该方法由编译器调用。理想情况下,解析的结果将被存储在常量池中,而不是在运行时重新进行解析。

我想说的是,用户定义的字面意义几乎是使值类型可用的一个要求,所以类似这样的东西可能会在未来出现。

总结

我喜欢字面符号。而且我真的希望能够定义我自己的字面意义!有什么想法?

有什么想法吗?