Скрытие экземпляра System.Random путем возврата функции

Следующий код взят из листинга Стильный F# 6: создание элегантного функционального кода для .NET 6 9-13:

let randomByte =
    let r = System.Random()
    fun () ->
        r.Next(0, 255) |> byte
// E.g. A3-52-31-D2-90-E6-6F-45-1C-3F-F2-9B-7F-58-34-44-
for _ in 0..15 do
    printf "%X-" (randomByte())
printfn ""

Автор заявляет: «Хотя мы вызываем randomByte() несколько раз, создается только один экземпляр System.Random()».

Я понимаю, что randomByte возвращает функцию, которая не создает экземпляр System.Random(), но мне кажется, что несколько экземпляров System.Random() все равно будут создаваться каждый раз через цикл for-do.

Я был бы признателен за объяснение того, как в этом случае не создаются несколько экземпляров System.Random().

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ключевым моментом является то, что randomByte — это не функция. Это значение с некоторой сложной логикой инициализации. Например, я мог бы написать:

let x = 5

Или я мог бы написать:

let x =
  let fourtyTwo = 42
  let thirtySeven = 37
  fourtyTwo - thirtySeven

И это будет эквивалентно. Оба объявляют значение с именем x и равным 5. Надеюсь, вы видите, что выражение fourtyTwo - thirtySeven оценивается только один раз, а не каждый раз, когда кто-то получает значение x.

Так что это работает и с randomByte: это значение с нетривиальной логикой инициализации. Во время инициализации этого значения сначала создается экземпляр System.Random, а затем создается анонимная функция, которая закрывается для этого экземпляра, и эта анонимная функция становится значением randomByte.

Другие вопросы по теме