constructor - TO 和 MAKE 的目的有何不同,它们记录在何处?

标签 constructor type-conversion rebol rebol3

我觉得我将 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/

相关文章:

c - 如何将 `SInt16' 转换为 `double'?

rebol - REBOL 对象的类型声明

regex - 从 Red 语言的字符串中删除特殊字符

scala - 如何从 Scala 中的派生类辅助构造函数调用辅助基类构造函数?

c# - 有没有办法在 C# 中进行动态隐式类型转换?

c++ - 重构建议 : How to avoid type checking in this OO design

unicode - Rebol 3 R3-GUI字段支持非ascii字符串输入吗?

javascript - 获取新对象的对象变量名

javascript - 原型(prototype)、对象、构造函数、 "this"、函数

javascript - JavaScript 中的函数与对象以及没有函数的实例化