2016-04-11 2 views

ответ

5

В F # 'T byref выглядит как обычный тип, но под прикрытием, это не так - она ​​соответствует ref и out параметров в C# и те специальные аннотации аргументов метода. Вот почему 'T byref немного странно в F #.

Я думаю, вы не сможете использовать его через обычную F функции #, так как функция T1 -> T2 скомпилирована как FSharpFunc<T1, T2> с методом T2 Invoke(T1 arg) - и вы не можете передать byref типа дженерик (как это не реальный типа).

Обойти это можно определить свой собственный делегат, который имеет byref тип:

type FastAction<'T> = delegate of 'T byref -> unit 

С этим, вы можете написать iter2D что итерирует непосредственно над массивом:

let iter2D (map:FastAction<'T>) (arr: 'T[][]) = 
    for y = 0 to arr.Length - 1 do 
     let row = arr.[y] 
     for x = 0 to row.Length - 1 do 
      map.Invoke(&arr.[y].[x]) 

Ниже будет мутировать значение внутри массива:

let arr = [| [| 0 |] |] 
iter2D (FastAction(fun a -> a <- 10)) arr 
+1

Что вы подразумеваете под словом 'by ref' не является реальным типом? Затем возвращается ['MakeByRefType()'] (https://msdn.microsoft.com/library/system.type.makebyreftype.aspx)? И что такое свойство ['IsByRef'] (https://msdn.microsoft.com/library/system.type.isbyref.aspx)? – PetSerAl

+0

Yuk, 'FastAction (fun bla ...)' вызывает 2 выделения ... Похоже, что нет никакого способа обойти это, но F # не имеет отдельного анонимного синтаксиса делегата, такого как C#. – Asik

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