和有什么区别
a: [b 1]
; and
a: [b: 1]
两者都给出相同的结果
> a/b
1
他们a/1
虽然不同。你什么时候用什么?第二个是一组,第一个是什么?
第二个是一组,第一个是什么?
您可以通过查看类型来获得答案:
>> 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-WORDs 可能会有所帮助。
在我看来,路径评估是粗略的。它作为一种语法便利而出现,但随后为从其他类型中选择的每种类型产生了行为的叉积。更不用说函数工作方式的差异了(这x: :append/dup/only/10/a
意味着什么?)
小例子:PATH!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 之间的差异说明了您所看到的差异。
对于其他类型,它变得更加奇怪。路径绝对是古怪的,并且可以使用某种宏大的统一理论。
第二个是一组,第一个是什么?
似乎您正在同时查看代码[b 1]
和[b: 1]
代码,但它们实际上只是数据。更准确地说,它们是两个元素的列表:一个word!
或set-word!
值后跟一个integer!
值。
a/b
是 的语法糖select 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]
作为旁注,请记住,lit-word 将评估为一个单词,有时由“word-decaying”规则引用:
red>> 'b
== b
/case
细化find
和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
阅读更多关于 Rebol 核心手册的路径:http ://www.rebol.com/docs/core23/rebolcore-16.html#section-2.10
你什么时候用什么?
对于a/b
vs的a/1
用法,要看你是想实现aselect
还是pick
操作。
对于[b 1]
vs [b: 1]
,这取决于块的后期使用。例如,如果您正在构建一个用作对象或地图规范的块,那么 set-word 形式更适合:
red>> a: [b:]
== [b:]
red>> append a 123
== [b: 123]
red>> c: object a
== make object! [
b: 123
]
此外,每次暗示“键/值”关系时,都应使用固定词形式,这会使您和其他读者的意图更加清晰。