我觉得我将 MAKE 理解为数据类型的构造函数。它有两个参数……第一个是目标数据类型,第二个是“规范”。
在对象的情况下,很明显 Rebol 数据 block 可以用作“规范”来取回对象类型的值!
>> foo: make object! [x: 10 y: 20 z: func [value] [print x + y + value] ]
== make object! [
x: 10
y: 20
]
>> print foo/x
10
>> foo/z 1
31
我知道如果你在创建一个 block 时传递一个整数,它会预分配足够的底层内存来容纳那个长度的 block ,尽管它是空的:
>> foo: make block! 10
== []
这有点道理。如果你传入一个字符串,那么你会得到解析成 Rebol 标记的字符串...
>> foo: make block! "some-set-word: {String in braces} some-word 12-Dec-2012"
== [some-set-word: "String in braces" some-word 12-Dec-2012]
并非所有类型都被接受,我会再次说到目前为止......非常好。
>> foo: make block! 12-Dec-2012
** Script error: invalid argument: 12-Dec-2012
** Where: make
** Near: make block! 12-Dec-2012
相比之下,TO操作的定义非常相似,只是它是为了“转换”而不是“构造”。它还将目标类型作为第一个参数,然后是“规范”。它对值的作用不同
>> foo: to block! 10
== [10]
>> foo: to block! 12-Dec-2012
== [12-Dec-2012]
这似乎是合理的。如果它收到一个非系列值,它会将它包装在一个 block 中。如果你尝试一个任意 block !对它有值(value),我想它会给你一个障碍!内部具有相同值的系列:
>> foo: to block! quote (a + b)
== [a + b]
所以我希望一个字符串被包裹在一个 block 中,但它只是做同样的事情 MAKE 做的:
>> foo: to block! "some-set-word: {String in braces} some-word 12-Dec-2012"
== [some-set-word: "String in braces" some-word 12-Dec-2012]
为什么 TO 与 MAKE 如此多余,它们之间的区别背后的逻辑是什么?将整数传递给 to block! 获取 block 内的数字(而不是使用特殊的构造模式),将日期传递给 to block! 而不是在 block 中生成日期与 MAKE 一样的错误。那么,为什么不希望一个字符串的 to block! 将该字符串放入一个 block 中呢?
还有:超越reading the C sources for the interpreter ,MAKE 和 TO 接受的每种目标类型的完整规范列表在哪里?
最佳答案
MAKE 是一个构造函数,TO 是一个转换器。我们拥有两者的原因是对于许多类型,操作是不同的。如果它们没有区别,我们可以通过一次手术完成。
MAKE 采用一个规范,该规范应该是对您正在构建的值(value)的描述。这就是为什么您可以传递 MAKE 一个 block 并获取诸如对象或函数之类的值,而这些值根本不像 block 。您甚至可以将整数传递给 MAKE,并将其视为分配指令。
TO 采用一个旨在更直接地转换为目标类型的值(这个值被称为“spec”只是一个不幸的命名错误)。这就是为什么输入中的值更直接地对应于输出中的值。只要有合理的默认转换,TO 就会执行。这就是为什么许多类型之间没有定义 TO 转换的原因,这些类型在概念上差异太大。我们对某些适合的类型进行了相当全面的转换,例如字符串和 block ,但也小心地限制了一些其他更有用的转换,例如从 none
到大多数类型。
在一些简单类型的情况下,确实没有描述类型的复杂方法。对于他们来说,让构造函数只将 self 描述的值作为他们的规范并没有什么坏处。巧合的是,对于相同的类型和值,这最终与 TO 的行为相同。这没有坏处,因此在这种情况下触发错误没有用。
没有关于 MAKE 和 TO 行为的全面文档,因为在 Rebol 3 中它们的行为没有完全确定。在某些情况下,关于什么是正确的行为仍然存在一些争论。我们正在努力使事情变得更加平衡,同时又不失去任何有值(value)的功能。例如,我们已经做了很多改进 none
和二进制转换的工作。一旦它们更加确定,一旦我们有地方放置它们,我们就会有更多的文档。与此同时,Rebol 2 的大部分行为都已记录在案,Rebol 3 的大部分更改目前都在 CureCode 中。
关于constructor - TO 和 MAKE 的目的有何不同,它们记录在何处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18839596/