之间有什么区别
a: [b 1]
; and
a: [b: 1]
两者都给出了相同的结果
> a/b
1
虽然它们与a/1
不同。
你什么时候用的?第二个是一组,第一个是什么?
答案 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/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]
作为旁注,请记住,一个单词将评估为一个单词,有时会被“单词衰减”规则引用:
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
来强制执行该行为的其他单词引用路径中的整数:
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表单,这样你的意图也会让你自己和其他读者更清楚。