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), переменной дескриптора уже нельзя будет воспользоваться.
"Состояние типов" очень уж напоминает обыкновенный union type, а Result<T,Error> с оператором? — монаду maybe
Или я не так понял?
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 удобном виде.
Так что автор конечно же мыслит в правильном направление, но мне кажется не до конца изучил уже существующие в данный момент наработки.
Прекрасные конечные автоматы на Rust — реализация на базе типажей From и Into.
Rust: состояния типов