Pull to refresh

Comments 15

Может дело в объектном моделировании?
Можно сделать функцию open() не собственным методами сущности File, а фабричным методом (например фабрики FileManager), ответственного за открытие файла. close() можно совместить с деструктором или, если нет деструкторов, то чем-то вроде AutoClousable и try-with-resources в Java. Главное что сам объект файла не сможет существовать в неоткрытом состоянии и становится недоступен после вызова close().

Ваш комментарий к Rust'у совершенно не применим. Попытаюсь объяснить почему:
1) File — это не сущность, File это тип. Создание дополнительного типа FileManager ничем не оправданно.
2) Функция File::open уже есть в стандартной библиотеке, и её идиоматичная реализация такова, что она либо возьмёт у ОС дескриптор и вернёт Ok(fd) или если не сможет, то приберёт за собой и вернёт Err(io::Error). Соответственно и попытаться воспользоваться файловым дескриптором будет невозможно, если File::open его не вернёт.
3) Никаких методов close у File нет. Вместо этого он реализует типаж(интерфейс) Drop, это означает что:
а) файловый дескриптор сам закроется как только выйдет из области видимости.
б) как только он будет закрыт(у дескриптора будет вызван метод drop), переменной дескриптора уже нельзя будет воспользоваться.

Почему же неприменим? Как раз в Rust сделано именно так как в этом комментарии было описано…
Я не совсем понял о чем вы пишите, но там идет речь про то, что компилятор укажет на ошибки на этапе компиляции. Деструкторов нет потому что они не нужны, есть trait Drop, если нужно закрыть какие-то внешние ресурсы.
Я думаю, что не только мне интересно, как выглядели состояния типов изначально. Можно какие ссылки?

"Состояние типов" очень уж напоминает обыкновенный union type, а Result<T,Error> с оператором? — монаду maybe
Или я не так понял?

UFO just landed and posted this here
Отличный перевод, побольше бы таких на хабре.
Не было бы умеснее перевести как «типизированное состояние»? Особенно в контексте второго примера.
Интересно, за что минус :|
UFO just landed and posted this here
Напомнило KindSignatures и DataKinds в Haskell:

  data SenderState
    = ReadyToSendHello
    | HasSentHello
    | HasSentNumber
    | HasReceivedNumber

  data Sender (a :: SenderState) = Sender SenderImpl

  sendHello :: Sender ReadyToSendHello -> Sender HasSentHello
  sendHello (Sender impl) = Sender $ send_message "HELLO" impl 

  waitRespondToHelloYou :: Sender HasSentHello -> Sender HasSentNumber
  waitRespondToHelloYou (Sender impl) = Sender $ ...


PS. Ещё singletons есть, но для этого случая они таки думаю overkill.
Описанная автором задача является очень распространённой в программирование и соответственно уже давно имеет хорошо проработанное решение с общеизвестным названием. Странно только что автор нигде его не обозначил. Это всем известный конечный автомат.

Что касается конкретных реализаций, то их тоже бывает множество, в зависимости от возможностей языка. Есть как наивные рантаймовые реализации через enum (в языках типа C), так и реализации через систему типов, как например здесь www.boost.org/doc/libs/1_66_0/libs/msm/doc/HTML/index.html. Более того, использование элементов метапрограммирования позволяет задавать эти самые зависимости между типами в таком www.boost.org/doc/libs/1_66_0/libs/msm/doc/HTML/ch03s04.html#d0e1462 удобном виде.

Так что автор конечно же мыслит в правильном направление, но мне кажется не до конца изучил уже существующие в данный момент наработки.
UFO just landed and posted this here
Sign up to leave a comment.

Articles