Почему у F # замыкания есть атрибут [<Serializable>]
? Что было бы практическим прецедентом?Почему F # закрывает сериализуемым?
Этот код демонстрирует сериализации и десериализации окончания:
open System
open System.IO
open System.Runtime.Serialization.Formatters.Binary
let formatter = BinaryFormatter()
let addTwo = (+) 2
(addTwo.GetType()).GetCustomAttributes false
|> Array.iter (fun attribute ->
printfn "Closure has attribute: %s" (attribute.GetType()).Name
)
let serializedClosure =
use memStream = new MemoryStream()
formatter.Serialize (memStream, addTwo)
memStream.ToArray()
Array.length serializedClosure
|> printfn "Serialized closure length: %d bytes"
let deserializedClosure =
use memStream = new MemoryStream (serializedClosure)
formatter.Deserialize memStream :?> Int32 -> Int32
deserializedClosure 3
|> printfn "Invoking deserialized closure: 2 + 3 = %d"
printfn "Press any key to exit..."
Console.ReadKey true |> ignore
Это работает, потому что закрытие компилируется в класс (обратите внимание на serializable
ключевое слово:
.class nested assembly auto ansi serializable beforefieldinit [email protected]
extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, int32>
{
.method assembly specialname rtspecialname instance void .ctor() cil managed {...}
.method public strict virtual instance int32 Invoke (int32 y) cil managed {...}
}
С именами закрытия (как [email protected]
) полностью зависимы от компилятора и меняются даже при небольшом изменении кода, мне было интересно, что является обоснованием создания сериализуемых замыканий?
это еще не закрытие - это просто функция ... действительно, большие проблемы возникают, как только начинают использовать закрытие внутри;) - но спасибо за вопрос - я не знал, что FSharpFunc сериализуем: D – Carsten
@ CarstenKönig, ну, ты прав. Но когда я компилирую код в режиме отладки, он определенно является закрытием, потому что '' 2 'еще не встроен и имя класса заканчивается на '' clo'' ;; –