Звучит как отличная концепция для языка, такого как F #, спасибо за интересную ссылку!
При программировании с массивами программисты F # используют точно такой же шаблон. Например, создайте изменяемый массив, обязательно инициализируйте его, верните его, а затем работайте с ним, используя функции, которые обрабатывают его как неизменяемый, например Array.map
(даже если массив действительно может быть видоизменен, так как нет временного массива ).
Использование типа seq <'a>: Один из способов сделать что-то подобное - преобразовать структуру данных в общую последовательность (seq<'a>
), которая является неизменным типом данных, и поэтому вы не можете (напрямую ) изменить исходную структуру данных с помощью seq<'a>
. Например:
let test () =
let arr = Array.create 10 0
for i in 0 .. (arr.Length - 1) do
arr.[i] <- // some calculation
Array.toSeq arr
Хорошо, что преобразованием обычно является O (1) (массивы / списки / .. реализуют seq<'a>
как интерфейс, так что это просто приведение). Однако seq<'a>
не сохраняет свойства исходной коллекции (например, эффективность и т. Д.), И вы можете обрабатывать ее только с помощью универсальных функций для работы с последовательностями (из модуля Seq
). Тем не менее, я думаю, что это относительно близко к шаблону переходных коллекций .
Аналогичный тип .NET также ReadOnlyCollection<'a>
, который упаковывает тип коллекции (несколько более мощный, чем seq<'a>
) в неизменяемую оболочку, чьи операции для изменения исключения броска коллекции.
Связанные типы: Для более сложных типов коллекций F # / .NET обычно имеют как изменчивую, так и неизменяемую реализацию (неизменяемую, поступающую из библиотек F #). Типы обычно очень разные, но иногда имеют общий интерфейс. Это позволяет использовать один тип, когда вы используете мутацию, и конвертировать его в другой тип, когда вы знаете, что он вам больше не понадобится. Однако здесь вам необходимо скопировать данные между различными структурами, поэтому преобразование определенно не является O (1). Это может быть что-то между O (n) и O (n * log n).
Примеры похожих коллекций: изменяемые Dictionary<'Key, 'Value>
с неизменяемыми Map<'Key, 'Value>
и изменяемые HashSet<'T>
или SortedSet<'T>
с неизменяемыми set<'T>
(из библиотек F #).