В чем разница между
a: [b 1]
; and
a: [b: 1]
оба дают одинаковые результаты для
> a/b
1
они отличаются для a/1
хотя. Когда вы что используете? А 2-й это комплект, а что 1-й?
В чем разница между
a: [b 1]
; and
a: [b: 1]
оба дают одинаковые результаты для
> a/b
1
они отличаются для a/1
хотя. Когда вы что используете? А 2-й это комплект, а что 1-й?
2-й набор, а что 1-й?
Вы можете получить ответы, посмотрев на тип:
>> type? first [b 1]
== word!
>> type? first [b: 1]
== set-word!
В чем разница
Когда вы используете выражение a/b
, вы пишете что-то, что действует как оператор SELECT, ища «любой тип слова», соответствующий b
в блоке, указанном a
, а затем возвращает элемент после него в блоке.
Красный следует наследию от 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
Красный, кажется, по крайней мере немного более последователен в этом, чем 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! уместно, то используйте его, в противном случае используйте СЛОВО!. С точки зрения реализации есть некоторые нюансы, которые выходят за рамки простого ответа (например, местные жители собираются в FUNCTION). Если вы знаете, что в конечном итоге что-то нужно будет преобразовать в задание, может быть полезно использовать SET-WORD.
Оценка пути схематична, на мой взгляд. Он возник как синтаксическое удобство, но затем произвел перекрестный продукт поведения для каждого типа, выбираемого из любого другого типа. И это не говоря уже о различиях в том, как работают функции (что означает x: :append/dup/only/10/a
?)
Маленький пример: ПУТЬ! поведение в Rebol использовало эвристику, где, если вы оцениваете путь, он будет действовать как ВЫБОР, если компонент пути является целым числом:
>> 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!
... но, как и выше, он будет действовать как 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 объясняет ту разницу, которую вы видите.
Это становится более странным для других типов. Пути определенно причудливы и могут использовать какую-то великую объединяющую теорию.
А 2-й это комплект, а что 1-й?
Кажется, что вы смотрите на [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
Подробнее о путях читайте в руководстве Rebol Core: http://www.rebol.com/docs/core23/rebolcore-16.html#section-2.10
Когда вы что используете?
Для использования a/b
против a/1
это зависит от того, хотите ли вы достичь операции select
или pick
.
Для [b 1]
против [b: 1]
это зависит от последующего использования блока. Например, если вы строите блок для использования в качестве спецификации объекта или карты, то форма set-word подходит лучше:
red>> a: [b:]
== [b:]
red>> append a 123
== [b: 123]
red>> c: object a
== make object! [
b: 123
]
Кроме того, вы должны использовать форму set-word каждый раз, когда вы подразумеваете отношение «ключ/значение», это делает ваше намерение более понятным для вас и других читателей.
you should use the set-word form each time you imply a "key/value" relationship
для меня это был ага-момент, спасибо за подробности
- person Wolfram Kriesing; 20.10.2016