2011-10-18 3 views
3

Рассмотрим следующий код:`` ref` против оператора присваивания mutable` с помощью F #

let mutable a = 0. 
let b = ref 0. 

a <- // works 
    printfn "%A" a 
    4. + 8. 

b := // does not work 
    printfn "%A" a 
    4. + 8. 

b := (// works 
    printfn "%A" a 
    4. + 8.) 

Почему оператор присваивания ссылок (: =) имеют различное поведение, чем изменяемом оператора присваивания (< -) ?

ответ

1

Опираясь на другие ответы ...

Более сложные выражения допускаются в пределах заданий, при условии, что окончательное выражение является одним из нескольких разрешенных форм. См. section 6.4.9 спецификации. Это позволяет сложные задания, такие как:

let x = 
    let rec gcd a = function 
    | 0 -> a 
    | b -> gcd b (a % b) 
    gcd 10 25 

Компилятор перемещает gcd к закрытому члену, но гнездование его в присвоении позволяет туже обзорный. С другой стороны, аргументы функции более ограничены. Они не создают новую область (что я знаю), и вы не можете определять функции, например, как часть выражения.

+0

Не могли бы вы более подробно остановиться на этом: «Они не создают новую область (что я знаю), и вы не можете определять функции, например, как часть выражение."? Пример был бы лучшим, поскольку я не уверен, что понимаю. –

+0

Я просто имею в виду, что вы не можете передать все после 'let x =' в моем примере выше как аргумент функции. Для аргументов функции требуются более простые выражения. Это объясняет, почему ': =', которая является функцией, и '='/'<-', которые являются операторами присваивания, ведут себя по-разному. – Daniel

2

Я могу дать лишь частичный ответ.

:= определяется в терминах <- в FSharp.Core \ чопорные-types.fs:

let (:=) x y = x.contents <- y 

В вашем примере

b := // does not work 
    printfn "%A" a 
    4. + 8. 

printfn "%A" a кажется, интерпретируется как y, которые не могут быть назначается ячейке int ref (неправильный тип). Сгруппировав все выражение с помощью (...), y теперь также содержит 4. + 8.. Возможно, оба оператора ведут себя по-другому, потому что <- представляется внутренним оператором (т. Е. Частью языка, а не библиотекой).

+0

Но я определенно ожидал, что оператор «<-» будет работать точно так же, как «: =», независимо от того, что на самом деле есть операторы. Поэтому они должны либо потерпеть неудачу, либо добиться успеха. Вам не кажется? –

+0

Да, это немного удивительно. – Frank

1

:= является функция (TRY (: =) ;; в FSI), которое имеет вид: 'a ref -> 'a -> unit

Так

b := // does not work 
    printfn "%A" a 
    4. + 8. 

в настоящее время анализируются как из-за инфиксный вызов разбора правила:

(:=) b (printfn "%A" a) 
4. + 8. 

Недопустимый как тип функции функции (: =). Другой пример:

let c = 10 + 
      11 
      12 

бы с 12 здесь

+0

Но это не объясняет, почему «правило синтаксического разбора инфикс», как вы его называете, не относится к '<-' (и' = 'в этом отношении), не так ли? Я по-прежнему полагаю, что различное поведение обусловлено (разумным) различием между встроенными и настраиваемыми операторами. – Frank

+0

Да, я согласен, встроенные операторы вроде <- имеют разные правила синтаксического анализа. В этом случае <- кажется, принимает результат полного блока, когда правила функций одинаковы для всех функций. Я предпочитаю вызывать: = как функцию – Ankur

0

Похоже, что расхождение в чувствительном к отступам парсере, а не что-то конкретно для этих операторов.

 Смежные вопросы

  • Нет связанных вопросов^_^