我刚刚在Rebol中遇到了这种语法来构造一些值:
>> #[email! "me@host.com"]
== me@host.com
这似乎等同于
>> to email! "me@host.com"
== me@host.com
和这个
>> #[string! "hello"]
== "hello"
虽然出现了这些错误:
>> #[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]
我想知道这是为了什么?它带来了什么好处?
答案 0 :(得分:4)
这种句法结构称为"construction syntax"(另见CureCode issue #1955)。它的存在理由是允许以其他方式直接表示的价值的文字形式。
有两类主要情况需要构造语法。
(1)直接值表示的构造语法
这个类的一个突出例子是对象! Rebol对象通常使用make object! [a: 42]
等代码创建。这不是结果对象值的直接文字表示,而是在评估时(在DO方言中)创建预期对象值的代码。构造语法允许直接表示值:#[object! [a: 42]]
。
其他典型示例包括#[none!]
和有些不规则(构造语法方面)#[true]
和#[false]
(请注意缺少!
)。围绕例如两者之间的差异包裹一个人的头部。 #[none!]
和none
将导致对Rebol语义的更深入理解(因此留给读者作为练习)。
(2)构造语法为“逃生机制”
此案例的典型示例是反向网址,例如您从reverse http://stackoverflow.com
获得的值。如果结果值将被序列化为纯URL!,则序列化表单将不再具有语法上的有效性:
>> /moc.wolfrevokcats//:ptth
** Script error: // does not allow unset! for its value2 argument
构造语法为这种情况提供了一种转义机制:
>> #[url! "/moc.wolfrevokcats//:ptth"] = reverse http://stackoverflow.com/
== true
这个特殊的例子也指出了一个有问题的情况:
>> reverse http://stackoverflow.com/
== /moc.wolfrevokcats//:ptth
可以说,此输出(由mold
native生成)是错误的:显示的结果不是相应值的有效词法表示。
有一些错误跟踪此类问题的特定实例(例如URL的CureCode issue #2010!)。针对更通用解决方案的一个提议是在MOLD的某些变体中建立往返检查:每当加载非构造语法MOLD的结果导致值与原始值不同时,此MOLD变体会回归到序列化到构造语法。