红色的“a:[b 1]”和“a:[b:1]”之间的区别是什么?

时间:2016-10-17 21:02:19

标签: rebol red

之间有什么区别
a: [b 1]
; and
a: [b: 1]

两者都给出了相同的结果

> a/b
1

虽然它们与a/1不同。 你什么时候用的?第二个是一组,第一个是什么?

2 个答案:

答案 0 :(得分:9)

  

第二个是一组,第一个是什么?

您可以通过查看类型获得答案:

>> type? first [b 1]
== word!

>> type? first [b: 1]
== set-word!
  

有什么区别

当您使用表达式a/b时,您正在编写类似于SELECT语句的内容,查找"任何单词类型"在b指示的块中匹配a,然后在块中返回该项后的内容。

Red遵循Rebol的传统 - 默认路径选择是"非严格" SELECT的形式,它使用"非严格的"平等的形式

>> (first [a:]) = (first [a]) ;-- default comparison
true

>> select [b 1] (quote b)
== 1

>> select [b: 1] (quote b)
== 1

要获得区分差异的严格行为,您需要使用/ CASE细化(在"区分大小写"意义上):

>> (first [a:]) == (first [a]) ;-- strict comparison
true

>> select/case [b: 1] (quote b)
== none

>> select/case [b: 1] (quote b:)
== 1

Red似乎至少比R3-Alpha更加一致,例如尊重1%和0.01的平等:

>> 1% = 0.01
== true ;-- both R3-Alpha and Red

>> select [0.01 "test"] 1%
== "test" ;-- in Red

>> select [0.01 "test"] 1%
== none ;-- in R3-Alpha

但它表明,在平等语义背后有一个有点狡猾的历史。

  

你什么时候使用?

好问题。 : - /在您的来源中使用符号,您应该使用您认为最适合您想表达的内容。如果你认为SET-WORD!是适当的然后使用它,否则使用WORD!在实现方面,有一些细微差别超出了简单答案的范围(例如,当地人聚集在FUNCTION中)。如果您知道某些内容最终需要转换为赋值,那么使用SET-WORD可能会有所帮助。

在我看来,路径评估是粗略的。它起因为语法上的便利,但随后为每种类型的每种类型产生了行为的交叉产物。那就是说功能如何工作x: :append/dup/only/10/a意味着什么?)

小例子:路径! Rebol中的行为使用了一种启发式方法,如果您正在评估路径,如果路径组件是整数,它将充当PICK:

>> numbers: [3 2 1]

>> pick numbers 3
== 1 ;-- because the 3rd element is a 1

>> select numbers 3
== 2 ;-- because 2 comes after finding a 3

>> numbers/3
== 1 ;-- acts like PICK because (...)/3 uses an INTEGER!

...但如上所述,如果被选中的东西是WORD,它将像SELECT(非严格)一样!:

>> words: [a b c]

>> select words 'a
== b ;-- because b is the thing after a in the block

>> pick words 'a
;-- In Rebol this is an error, Red gives NONE at the moment

>> words/a
== b ;-- acts like SELECT because (...)/a uses a WORD!

因此,SELECT和PICK之间的区别在于您所看到的差异。

其他类型更奇怪。路径绝对是古怪的,可以使用某种宏大的统一理论。

答案 1 :(得分:2)

  

第二个是一组,第一个是什么?

您似乎将[b 1][b: 1]视为代码,但它们实际上只是数据。更确切地说,它们是两个元素的列表:word!set-word!值后跟integer!值。

a/bselect a 'b的语法糖,它检索'b字后面的值(在内部使用find调用)。为方便起见,搜索'b也与其他单词类型匹配:

red>> find [:b] 'b
== [:b]
red>> find [/b] 'b
== [/b]
red>> find ['b] 'b
== ['b]
red>> find [b] 'b
== [b]

作为旁注,请记住,一个单词将评估为一个单词,有时会被“单词衰减”规则引用:

red>> 'b
== b
/casefind

select细化将采用更严格的匹配,确保类型也相同。虽然,您显然无法将其与路径表示法一起使用,但您需要使用select/case调用替换路径。

因此,两者都为a/b提供了相同的结果,因为两者都会返回b字后面的值(不管他的“字子类型”):

red>> [b 1] = [b: 1]        ;-- loose comparison, used by `find` and `select`.
== true
red>> [b 1] == [b: 1]       ;-- strict comparison, used by `find/case` and `select/case`.
== false
  

虽然它们与a / 1不同。

整数值在路径中具有特定的语义。它们充当pick的糖,因此a/1相当于pick a 1。您还可以通过将get-word!值设为red>> c: 1 == 1 red>> a: [b 123] == [b 1] red>> a/:c == b red>> a: [b: 123] == [b: 123] red>> a/:c == b: red>> c: 2 == 2 red>> a/:c == 123 来强制执行该行为的其他单词引用路径中的整数:

a/b

阅读Rebol Core手册中有关路径的更多信息:http://www.rebol.com/docs/core23/rebolcore-16.html#section-2.10

  

你什么时候使用?

对于a/1 vs select用法,这取决于您是否希望实现pick[b 1]操作。

对于[b: 1] vs red>> a: [b:] == [b:] red>> append a 123 == [b: 123] red>> c: object a == make object! [ b: 123 ] ,它取决于稍后使用该块。例如,如果您正在构建一个用作对象或地图规范的块,那么设置字形式更适合:

{{1}}

此外,每当你暗示一个“键/值”关系时,你应该使用set-word表单,这样你的意图也会让你自己和其他读者更清楚。