我刚刚在 Rebol 中遇到了这个语法来构造一些值:
>> #[email! "me@host.com"]
== me@host.com
Run Code Online (Sandbox Code Playgroud)
这似乎相当于
>> to email! "me@host.com"
== me@host.com
Run Code Online (Sandbox Code Playgroud)
和这个
>> #[string! "hello"]
== "hello"
Run Code Online (Sandbox Code Playgroud)
虽然出现这些错误:
>> #[integer! 1]
** Syntax Error: Invalid construct -- #[
** Near: (line 1) #[integer! 1]
>> #[decimal! 1]
** Syntax Error: Invalid construct -- #[
** Near: (line 1) #[decimal! 1]
>> #[string! 1]
== [string! 1]
Run Code Online (Sandbox Code Playgroud)
我想知道这是做什么用的?它带来什么好处?
这种语法结构称为“构造语法”(另请参阅CureCode issues #1955)。它存在的理由是允许使用文字形式来表示无法直接表示的值。
\n\n有两类主要情况需要构造语法。
\n\n(1) 直接值表示的构造语法
\n\n此类的一个突出示例是 object!。Rebol 对象通常使用诸如make object! [a: 42]. 这不是结果对象值的直接文字表示,而是在评估时(在 DO 方言中)创建预期对象值的代码。构造语法允许直接表示值:#[object! [a: 42]]。
其他典型的例子是#[none!]and 有点不规则(结构语法方面)#[true]and #[false](注意缺少!)。了解eg#[none!]和之间的差异none将导致对 Rebol 语义的更深入理解(因此留给读者作为练习)。
(2) 作为“逃逸机制”的构造语法
\n\n这种情况的典型示例是反向 URL,例如您从 获取的值reverse http://stackoverflow.com。如果结果值被序列化为纯 URL!,序列化形式在语法上将不再有效:
>> /moc.wolfrevokcats//:ptth\n** Script error: // does not allow unset! for its value2 argument\nRun Code Online (Sandbox Code Playgroud)\n\n构造语法为这种情况提供了转义机制:
\n\n>> #[url! "/moc.wolfrevokcats//:ptth"] = reverse http://stackoverflow.com/\n== true\nRun Code Online (Sandbox Code Playgroud)\n\n这个特殊的例子也指出了一个有问题的情况:
\n\n>> reverse http://stackoverflow.com/\n== /moc.wolfrevokcats//:ptth\nRun Code Online (Sandbox Code Playgroud)\n\n可以说,这个输出(由mold机生成)是错误的:显示的结果不是相应值的有效词汇表示。
有一些错误跟踪此类问题的特定实例(例如CureCode issues #2010URL 的针对更通用解决方案的一项建议是在 MOLD 的某些变体中内置往返检查:每当加载非构造语法 MOLD 的结果导致值与原始值不同时,该 MOLD变体将退回到序列化到构造语法。
\n