Я бы для type state pattern скорее привёл такой пример (который я встречал на практике): Билдер, у которого есть обязательные поля, но при этом эти поля можно задать разными способами.
// Наша структура
struct MyStruct {
data: MyData
}
// Состояние билдера, которое сообщает что нужно указать data
struct NeedsData;
// Состояние билдера, которое сообщает что можно билдить
struct ReadyToBuild;
// билдер
struct MyStructBuilder<State> {
data: Option<MyData>,
pd: PhantomData<State>
}
impl MyStruct {
// возвращает билдер, который требует data
fn builder() -> MyStructBuilder<NeedsData> {...}
}
impl MyStructBuilder<NeedsData> {
// поглощает билдер, устанавливает data, возвращает билдер который уже можно билдить
fn with_bin_data(self, data: &[u8]) -> MyStructBuilder<ReadyToBuild>
{...}
// поглощает билдер, читает из файла и устанавливает data, возвращает билдер который уже можно билдить
fn with_data_from_file(self, path: &Path) -> MyStructBuilder<ReadyToBuild>
{...}
}
impl MyStructBuilder<ReadyToBuild> {
// в таком состоянии уже можно билдить
fn build(self) -> MyStruct {...}
}
impl<T> MyStructBuilder<T> {
// здесь можно расположить всякие общие методы билдера
}
То есть мы тут обязаны задать у билдера data (удобным нам способом) и только после этого можем вызвать build().
Из статьи не понятно что возвращает get_email(), если это &Email, то трюк с "new(), get_email(), promote(), используем email" не сработает (потому что пока мы владеем ссылкой на email, мы не можем сделать promote()). Если же метод клонирует email, то сработает. (Не понятно почему в статье присутствует метод get_email() и при этом сам email у User аубличное поле, будем считать что оно приватное на самом деле)
По крайней мере некоторые особенности rust делают использование этого подхода более простым. Например использование Result в возвращаемом значении функции. Это частный случай использования enum в rust. При обработке enum помогает pattern matching, которого например в c++ нет:
Плюс, работу с Result упрощает синтаксический сахар в виде `?`. Или например то что описано в последней главе статьи. Там используются методы (у User), котоыре принимают self в качестве ресивера, то есть после вызова такого метода ресивер поглощается и на нём больше нельзя вызывать методы, это возможно благодаря borrow checker'у в rust. Не знаю можно ли реализовать нечто подобное в c++ или Java, я слышал что в c++ есть какое-то подобие move семантики, но честно говоря в продвинутом c++ не разбираюсь.
В Rust крейт это библиотека на Rust, которую можно подключить к своему проекту в качестве зависимости. Если проводить аналогии с другими языками, то это то же, что и пакеты в Python или JS.
Я создал запрос из сериализованной встроенной структуры данных хэш-карты в Rust. Я провел сериализацию, так как запрос принимает текст, я преобразовал структуру хэшмапа в строку. Потом я сделал этот запрос и в ответ получил обработанный ответ. Ответ был дан структуре, то есть я сделал десериализацию. Дальше я провел структурирование, создал структуру логина и с помощью метода json для ответа вывел ее в структуру
Написано скомкано, для человека не знакомого с вашим кодом читается как абракадабра. Тут бы сначала подвести к решаемой задаче (например написать откуда взялась эта хэш карта, вы её создали, она уже есть в проекте). Само решение задачи написать поподробнее и для наглядности с отрывками кода. Либо, если как вы решали конкретную задачу не релевантно для статьи в целом, то этот отрывок можно вообще вырезать.
Я бы для type state pattern скорее привёл такой пример (который я встречал на практике): Билдер, у которого есть обязательные поля, но при этом эти поля можно задать разными способами.
То есть мы тут обязаны задать у билдера data (удобным нам способом) и только после этого можем вызвать build().
Из статьи не понятно что возвращает get_email(), если это &Email, то трюк с "new(), get_email(), promote(), используем email" не сработает (потому что пока мы владеем ссылкой на email, мы не можем сделать promote()). Если же метод клонирует email, то сработает.
(Не понятно почему в статье присутствует метод get_email() и при этом сам email у User аубличное поле, будем считать что оно приватное на самом деле)
По крайней мере некоторые особенности rust делают использование этого подхода более простым. Например использование Result в возвращаемом значении функции. Это частный случай использования enum в rust. При обработке enum помогает pattern matching, которого например в c++ нет:
Плюс, работу с Result упрощает синтаксический сахар в виде `?`.
Или например то что описано в последней главе статьи. Там используются методы (у User), котоыре принимают self в качестве ресивера, то есть после вызова такого метода ресивер поглощается и на нём больше нельзя вызывать методы, это возможно благодаря borrow checker'у в rust. Не знаю можно ли реализовать нечто подобное в c++ или Java, я слышал что в c++ есть какое-то подобие move семантики, но честно говоря в продвинутом c++ не разбираюсь.
В Rust крейт это библиотека на Rust, которую можно подключить к своему проекту в качестве зависимости. Если проводить аналогии с другими языками, то это то же, что и пакеты в Python или JS.
Написано скомкано, для человека не знакомого с вашим кодом читается как абракадабра. Тут бы сначала подвести к решаемой задаче (например написать откуда взялась эта хэш карта, вы её создали, она уже есть в проекте). Само решение задачи написать поподробнее и для наглядности с отрывками кода.
Либо, если как вы решали конкретную задачу не релевантно для статьи в целом, то этот отрывок можно вообще вырезать.