кажется, что когда вы используете «let .. in», вы можете переопределить настройку «#light» по умолчанию, которая заключается в том, что пробел является значительным, поэтому я думаю, что именно так и происходит в этом случае, и почему вы не получаете никаких предупреждений / ошибка во втором случае (вы добавили 'in', поэтому компилятор считает, что вы хотите явно указать область действия). Это кажется немного странным, так что это может быть ошибкой. Я уверен, что Брайан из команды F # скоро ответит на это сомнение: -).
В любом случае, я думаю, что компилятор обрабатывает ваш второй пример так же (используя более простой пример компиляции):
open System
let ar = new ResizeArray<_>() in
let rnd = new Random();
ar.Add(rnd.Next())
printfn "%A" (rnd.Next())
Вы можете заставить его обращаться с ним так, как вам хочется, если вы добавите скобки и напишите что-то вроде этого:
let ar = new ResizeArray<_>() in
(let rnd = new Random()
ar.Add(rnd.Next()))
printfn "%A" (rnd.Next())
В общем, вы можете использовать скобки для указания областей в любом месте программы F #. Например, вы можете написать:
let a = 1
(let a = a + 10
printfn "%d" a)
printfn "%d" a
В этом примере выводится «10», а затем «1». Конечно, это не кажется очень практичным, но это полезно при использовании ключевого слова use
, которое ведет себя как let
, но работает для объектов IDisposable
и гарантирует, что объект удаляется, когда покидает область видимости. (это как using
в C #):
let some = new Some()
(use file = new StreamReader(...)
let txt = file.ReadToEnd()
printfn "%s" txt)
doSomething() // continue, 'file' is now closed!
EDIT :
Я совершенно забыл упомянуть важный момент - первый способ написания кода кажется мне более естественным (и он полностью использует преимущества «простого» синтаксиса #light, предлагаемого F #), поэтому я бы предпочел его :-).