Java有一些用于创建数值的字面符号,但如果我们有更多的字面符号,那不是很好吗?
当前的字词
这些是我们今天可以在Java中写的一些字面符号。
- 整数 -
123,12s,1234L,0xB8E817,077。0b1011_1010 - 浮点 -
45.6f,56.7d。7.656e6 - 字符串 -
"Hello world" - char -
'a' - boolean -
true。false - 空------。
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和语言的人更有资格决定。 不过很明显,需要在用户类上有某种形式的工厂方法来执行解析,该方法由编译器调用。理想情况下,解析的结果将被存储在常量池中,而不是在运行时重新进行解析。
我想说的是,用户定义的字面意义几乎是使值类型可用的一个要求,所以类似这样的东西可能会在未来出现。
总结
我喜欢字面符号。而且我真的希望能够定义我自己的字面意义!有什么想法?
有什么想法吗?