Кому и зачем нужен Rust? Как стать Rust-разработчиком?

Поговорим о языке программирования, который в последние годы быстро набирает популярность:

*https://www.youtube.com/watch?v=Gr6bnv41mkY
**https://300.ya.ru/v_pKNOK4a9

таймкоды

00:00:00 Введение в Rust

  • Rust — основной язык для разработки в блокчейне, особенно в Slate.
  • Подходит для создания микросервисов и рантайм-критического кода, например, для трейдинга.
  • Активно развивается и имеет хорошие библиотеки для блокчейна, особенно для Ethereum.

00:01:32 Особенности Rust

  • Быстродействие благодаря отсутствию garbage collector и implicit memory copy.
  • Строгие проверки доступа к памяти на этапе компиляции.
  • Обязательная проверка результатов, что предотвращает пропуски ошибок.

00:03:26 Трудности миграции

  • Переписывание кода с C++ на Rust часто требует пересмотра дизайна.
  • Примеры различий: сложение NaN и Overflow в Rust требуют специальных функций.

00:05:13 Принципы языка Rust

  • Модель памяти: по умолчанию память перемещается, а не копируется.
  • Трейс: особая конструкция, похожая на интерфейсы.
  • Объектная модель: отличается от традиционной.
  • Подход к параллелизму: поддерживает традиционные модели, но имеет свои особенности.

00:06:47 Модель памяти

  • Память по умолчанию перемещается, а не копируется.
  • Пример с String: при присваивании переменной происходит перемещение ресурса.
  • Использование borrows для передачи переменных по ссылке.

00:10:24 Клонирование и мьютабилити

  • Клонирование переменной требует явного указания.
  • Мьютабилити: переменные по умолчанию неизменяемы, для изменения нужно явно объявить mutable.
  • Эксклюзивный доступ через мьютабильную ссылку: другие ссылки становятся запрещены.

00:12:04 Введение в трейды

  • Трейды в Rust обязательны для понимания языка.
  • В отличие от интерфейсов в других языках, в Rust все типы используют трейды.
  • Стандарт языка содержит множество трейдов, которые определяют поведение типов.

00:13:04 Примеры использования трейдов

  • Операторы в Rust определяются через трейды.
  • Интеджеры имплементируют более 400 трейдов.
  • Для определения операций на структурах используются стандартные трейды, например, Add.

00:13:26 Определение операций на структурах

  • Пример определения сложения на структуре с двумя интеджерами.
  • Функция Add позволяет выполнять операции сложения.
  • Этот подход более универсален и понятен по сравнению с перегрузкой операторов.

00:14:52 Специальные трейды и их применение

  • Специальные трейды необходимы для клонирования, дебаг-принтов и передачи объектов между потоками.
  • Трейды можно передавать как параметры функции или использовать в дженериках.

00:15:45 Объектная модель в Rust

  • В Rust нет классов, вместо них определяются структуры и их имплементации.
  • Псевдоконструкторы new создают новые инстансы объектов.
  • Функция make_copy копирует объект.

00:16:44 Дженерики и трейды

  • Дженерики требуют реализации трейда Clone для использования.
  • Большинство типов по умолчанию реализуют Clone.
  • Макросы позволяют легко определять стандартные трейды.

00:20:04 Параллелизм в Rust

  • Rust поддерживает традиционную потоковую модель и асинхронную модель.
  • Асинхронная модель оптимизирует ресурсы, используя пул потоков и idle-время.
  • Традиционная модель предпочтительна, когда каждый поток работает с полной загрузкой.

00:22:21 Модель Tokio

  • Модель Tokio использует пул потоков и idle-время для оптимизации производительности.
  • Эта модель эффективна, когда потоки работают с перерывами.

00:22:35 Модель Tokio для серверной части

  • Tokio полностью реализует асинхронную модель, что удобно для написания серверов и микросервисов.
  • Модель позволяет экономить ресурсы.

00:23:35 Синхронизация на уровне данных

  • Вместо блокировки кода мьютексы блокируют данные, оборачивая их в себя.
  • Доступ к данным осуществляется после их блокировки мьютексом.
  • Остальные потоки ждут освобождения мьютекса.

00:24:27 Эксклюзивный доступ и безопасность

  • Мьютекс позволяет получить эксклюзивный доступ к данным.
  • Компилятор блокирует передачу необёрнутых объектов между потоками.
  • Для безопасного использования объектов необходимо оборачивать их в мьютекс.

00:25:57 Модели мьютексов

  • В Tokio мьютекс работает как синхронная функция, ожидая освобождения объекта.
  • В традиционной потоковой модели мьютекс блокирует код.
  • Автор предпочитает использовать Tokio мьютекс.

00:27:26 Контроль памяти и лайфтайм

  • Лайфтайм используется для передачи ссылок на структуры, чтобы избежать их преждевременного освобождения.
  • Без лайфтайма невозможно передать ссылку на структуру, которая умрёт до того, как ссылка будет доступна.

00:29:08 Строгое соответствие типов

  • Строгое соответствие типов между различными типами данных.
  • Конвертация типов возможна только при отсутствии опасности оверфлоу.

00:29:50 Трудности вхождения в Rust

  • Rust имеет сложный синтаксис с множеством дженериков и вариантов объявления типов.
  • Новичкам сложно понять код из-за разнообразия синтаксических конструкций.
  • Опыт работы с другими языками помогает лучше понять Rust.

00:33:58 Советы для разработчиков

  • Учиться на примерах, например, на ресурсе Rust Examples.
  • Понимать основные принципы языка, включая модель памяти.
  • Начинать с простых задач и постепенно усложнять их.

00:34:47 Переход на Rust

  • Переход на Rust имеет смысл для написания новых сервисов с нуля.
  • Портирование существующих проектов может быть сложным и дорогостоящим из-за необходимости переделки дизайна.

00:36:14 Проблемы языка Rust

  • Rust — молодой и не до конца устоявшийся язык.
  • Возможность объявления блоков кода unsafe для портирования существующих проектов.
  • Небезопасный код остаётся небезопасным, что вызывает вопросы о целесообразности такого подхода.

00:37:07 Проблемы с библиотеками

  • Большое количество сырых библиотек, требующих времени для выбора наиболее стабильной.
  • Необходимость тщательного анализа библиотек для решения задач.

00:38:05 Управление памятью в Rust

  • Переменные освобождаются при выходе из scope: в конце функции или блока.
  • Деструкторы вызываются автоматически при выходе переменной из scope.

00:38:57 Сравнение с Go

  • Rust заимствовал многие черты от Go, включая объектную модель.
  • Оба языка подходят для серверных бэкенд-сервисов, но Rust предлагает больше возможностей.
  • В критичных по производительности и памяти задачах Rust предпочтительнее из-за более тонкого управления памятью.

00:40:41 Переход с C++ на Rust

  • Переход может быть затратным, особенно если существующие продукты не имеют unsafe-дизайна.
  • Иногда проще написать новую версию с нуля, чем портировать старую.
  • Ресурсы на редизайн могут не окупить затраты.

00:42:30 Переход с C# на Rust

  • C# тесно интегрирован с экосистемой Microsoft, поэтому переход на Rust может быть нецелесообразным.
  • Если проект не привязан к экосистеме Microsoft, C# может быть предпочтительнее.

00:43:32 Сложность освоения Rust

  • Освоение Rust может показаться сложным без знания основных принципов.
  • Для тех, кто знаком с C++ или Go, переход будет легче.
  • Знание принципов Rust облегчает освоение языка.

00:45:02 Применение Rust

  • Rust активно используется в блокчейне и финансовых трейдинг-системах.
  • Новые продукты в этих областях пишутся на Rust.

00:45:26 Введение в Rust

  • Автор планирует рассказать о ресурсах для обучения Rust.
  • Опыт работы с Rust менее года, начал с блокчейн-стартапа.
  • Осваивал конструкции и библиотеки Rust, работал над солверсами для блокчейна.

00:47:01 Опыт в других стеках

  • Общий опыт разработки около 20 лет, 17 лет в Google.
  • Опыт работы с C++, Python, Java, Go и фронтендом JavaScript.

00:47:34 Рынок труда и требования

  • Первую работу найти сложно, нужен бэкграунд и портфолио.
  • Требования к кандидатам на Rust аналогичны другим стекам.
  • Важны не только хард-скиллы, но и софт-скиллы.

00:49:47 Область применения Rust

  • Rust — многопрофильный язык с обширным набором библиотек и фреймворков.
  • Важно выбирать стабильные библиотеки для надёжной работы.

00:50:42 Бинарная совместимость и фреймворки

  • Проблемы с конфликтами зависимостей не встречались.
  • Cargo — простой и интуитивно понятный фреймворк для сборки.

00:51:49 Сравнение с Java и Kotlin

  • Kotlin ассоциируется с Android-приложениями.
  • Rust удобнее для других задач, чем Java и Kotlin.
  • В Rust нет инжекшна, в отличие от Java.

00:53:42 Переписывание кода на Rust

  • Переписывание Java-кода на Rust выгодно для сервисов, требующих быстродействия.
  • Код становится более понятным и менее запутанным.

00:55:13 Дебаггинг в Rust

  • Дебаггинг требует длительного пристального взгляда.
  • Встроенный помощник в Visual Studio Code помогает с подсказками.
  • Автор предпочитает дебаг-трейсинг.

00:56:42 Динамическая память в Rust

  • Память в Rust по умолчанию динамическая.
  • Объекты уничтожаются при выходе из области видимости или при достижении счётчика ссылок нуля.

00:58:32 Поддержка машин Лелинга и Конту Компьютинга

  • Автор не сталкивался с поддержкой этих технологий в Rust.

00:59:10 Совместимость языков

  • Языки C и C++ совместимы по парадигмам, но не по дизайну.
  • При портировании кода могут возникнуть проблемы с ансей-конструкциями.
  • В Rust нельзя вернуть ссылку на объект, только сам объект.

01:00:25 Применение Rust

  • Rust используется не только в блокчейне, но и в трейдинге, финансах и фронтенде.
  • В блокчейне Rust необходим для работы с криптографией.

01:01:02 Кросс-вызовы

  • Кросс-вызовы между C и Rust возможны, но небезопасны.
  • C-код может вызвать панику в Rust-коде.

01:02:02 Трейты и структуры

  • Можно определить трейт для структуры, если она публичная и имеет доступ.
  • Трейты не привязаны к конкретным структурам, а представляют собой совокупность функций.

01:04:33 Имплементация трейтов

  • Можно имплементировать трейт для любой структуры данных.
  • Если для всех полей структуры определены трейты, можно вывести трейт для всей структуры через макрос.

01:06:21 Ограничения трейтов

  • Трейты накладывают ограничения на использование структур.
  • Если функция не используется, трейт не обязателен.

01:11:14 Принципы ООП в Rust

  • В Rust нет наследования, но есть полиморфизм через трейты и дженерики.
  • Инкапсуляция возможна через имплементацию трейтов.

01:12:32 Заключение

  • Благодарность за внимание и обратную связь.
  • Анонс подготовки продвинутого курса по Rust.

В этом видео

Преимущества и недостатки Rust. Где используется?
0:00
Значит, первое, что я бы хотел, это рассказать про общие ожидания. Ну, для начала для чего и кому
0:05
нужен раст. Я бы сказал так, что в блокчейне раст почти необходим. Вот
0:10
довольно много сейчас вещей делается в блокчейне ещё на Го, вот даже на Джаве
0:15
есть, вот на C++се, но основной язык сейчас. Например, вот ээ в Салане там
0:22
просто только на Расте пишутся ээ программы на блокчейне. Ну, смарт тоже называлось смарт-контракты. Э,
0:30
влани называется программы, они пишутся только на раст, поэтому это необходимо.
0:35
Ну, также это, в общем-то, любой разработчик, который пишет скажем так, сервисы,
0:41
майкросервисы, вот, ээ, какой-то, скажем так, ээ, runtime critical code, то есть,
0:48
скажем, трейдинг и так далее. В этом случае очень хорошо для этого подходит.
0:54
То есть, в общем-то, на нём можно создавать как фронтэнд, так и бэкэнд, я так скажу. В основном, конечно, на
1:01
фронтэнде тоже есть эксперименты, но я с фронтэндом не работал на раз. В основном работаю с бэкэндом. То есть любые
1:08
сервисы, которые создаются на любом другом языке, раз для этого прекрасно подходит. Ничего специфического в нём
1:13
нет, я бы сказал. Вот. Ну и кроме того, в нём, как я сказал, хорошие библиотеки для
1:19
блокчейна. То есть, например, для Этерриума библиотеки гораздо лучше, чем
1:24
для Го. И они активно развиваются. И сам по себе язык молодой активно
1:32
развивающийся. Вот. И главное его, скажем так, ээ ну, фичи — это
1:38
быстродействие и безопасность. За счёт чего он быстродействующий? Это то, что, во-первых, в нём нет гарбадж
1:46
коллектора. Вот. И, во-вторых, никогда память по умолчанию не копируется, если
1:51
не сказать ей копироваться эксплитли. Я чуть позже рассмотрю модель памяти и, в общем, там покажу на маленьком
1:57
примерчике, как это работает. Вот. И кроме того, очень важный момент — это строгие проверки
2:04
доступа к памяти. То есть на этапе компиляции раз отсекает
2:10
заведомо небезопасные вещи, что, в общем-то, ну, ускоряет
2:15
разработку, позволяет выяснить, выявить потенциальные ошибки на этапе компиляции. Ну и, кроме того,
2:22
results, то есть без проверки результата невозможно идти дальше, то есть невозможно просто пропустить
2:28
ошибку. Вот, и выяснить, что там образится к результату, например, которого нет.
2:34
То есть там нет такого, что, скажем, он возвращает нал, и вы по ошибке там пытаетесь от этого нала что-то взять.
2:40
Ну, грубо говоря, там нужно там либо ошибка, либо действующий
2:46
результат. Чем-то похоже на гон, но, скажем так, более строго и более
2:53
развёрнуто. Вот я постараюсь, на самом деле, в этом выступлении особо не зацикливаться на сравнении с другими
3:00
языками, потому что аудиос у нас достаточно большой. Ну и, в общем-то, не для всех будут понятны сравнения с
3:06
некоторыми языками, потому что, я понимаю, люди у нас, ну, имеют опыт с разными стеками. Поэтому я буду
3:12
стараться, ну, говорить так, как будто бы, ээ, в общем-то, ну, знакомить Растом с нуля,
3:20
без сравнения с существующими парадигмами, с другими языками. О’кей, поехали дальше. Вот
3:27
здесь мы подходим к наиболее интересному вопросу. На что люди больше всего жалуются, это трудности миграции.
3:33
Существует такое мнение, скажем так, завышенное ожидание, что системный код
3:38
на CC++ легко переписать на раст. Я бы сказал, что это почти никогда неправда.
3:45
Ну просто потому, что проблема в разнице в дизайне кода. Главное — это, так сказать, не язык, а дизайн. Вот если код
3:52
задизайнен безопасно, скажем, на тонусе плюс-плюс, его можно или там на любом другом языке, его можно на раз
3:58
переписать легко. Но если как бы дизайн изначально unсей, то придётся
4:04
переделывать дизайн сначала перед тем, как переписать. Это, по сути, не портирование существующего кода, а, ну,
4:11
создание заново, создание его заново с редизайном. Вот это это вот моё такое вот мнение на эту тему. То, что я вот
4:18
видел уже на примерах существующего кода. И когда я начал программировать на раз, я понял, что так как я программирую на
4:25
раз, я на C++се бы не программировал. Я бы написал такое, что потом на раз не портировать так просто. Вот я яркий
4:31
пример. Например, signed uns C++ мы никогда не задумываемся почти. Мы просто
4:36
прибавляем одно к другому и всё. А в расте это работать не будет. То есть компилятор вот такую конструкцию, как
4:42
попытка сложить unside assign просто отсечёт. Он ошибку выдаст.
4:48
Для того, если мы очень это хотим сделать, надо вызывать специальную функцию, но по умолчанию вот это сделать
4:55
невозможно, скажем так. Вот то же самое с overflows. Если там в C++ мы просто
5:02
складываем, то в раст мы как бы должны разрешить overflows explicitly, и только
5:08
потом это можно будет делать. Иначе, ну, это на этапе компиляции компилятор будет ругаться в тех случаях, когда, в
5:14
принципе, оверфло возможно.
Обзор принципов языка
5:20
Вот теперь я хочу немножечко рассказать про принципы языка. В общем-то, самое интересное это, ну, чтобы помочь, ээ,
5:27
как бы аудитории понять, с какой стороны на него смотреть правильно и, ну, как в него проще
5:34
входить и как проще понимать, с чего начинать, если для тех, кто хочет с ним знакомиться.
5:41
Значит, я для себя, когда только начал программировать, выделил четыре момента.
5:47
Я это почепнул, сразу скажу, не из книжек, не из документации, а то, что вот я для себя лично
5:53
выделил, на что следует обратить внимание и что следует изучить в первую очередь про язык. Первое — это модель
6:01
памяти. Вот это, ну, собственно, как память в нём устроена по умолчанию. И когда, ну,
6:08
пишешь код, на что надо обратить внимание, когда дизайнишь код, на что надо обратить внимание и как бы как
6:13
правильно понять то, что язык предлагает. Второе — это trades. Вот сразу скажу, что trades —
6:20
это совершенно особая конструкция, скажем так. Ээ её можно назвать это как интерфейсы, но не интерфейсы. Вот. То
6:28
есть, чтобы было понятно, о чём я говорю. Вот это это как интерфейс он опять же это отличается. Я потом покажу,
6:35
в чём отличие основное. Третье — это объектная модель, которая отличается от
6:41
традиционной, которая похожа на некоторые языки, скажем, на, но имеет свои особенности.
6:47
И четвёртое — это подход к параллелизму, который опять
6:52
же, скажем так, где в Раце стремились разработчики языка
6:58
к своей модели, хотя он поддерживает и другие традиционные. Опять же я, когда мы будем идти дальше, я расскажу. Так,
7:06
ну теперь я предлагаю пройтись по каждой из по каждому из этих принципов. Вот, значит, модель памяти. В
Модель памяти
7:12
первую очередь любая память по уволчанию у нас. Что это означает? Что когда мы
7:17
объявляем какую-то переменную и, скажем, присваиваем её либо передаём как
7:24
параметр, мы всегда перемещаем эту память. Мы никогда её не копируем
7:32
изначально. Вот это такой момент. То есть, скажем, это позволяет изначально экономить
7:37
память. То есть, если мы копируем, мы должны копировать explicit, как бы сказать, что мы копируем. Иначе у нас
7:45
память просто перемещается. Как это выглядит? Например, вот первый фрагмент кода. Если мы, допустим, какой-то стринг
7:50
присваиваем переменной А, потом переприваиваем его в переменную B, мы перемещаем ресурс с переменной А в
7:57
переменную B, и переменная А становится невалидной. У нас компилятор делает ошибку на
8:02
этом. Вот это первый такой момент, который, ну, для многих сразу очень
8:08
непонятен. Но если мы, как говорится, это усвоим, сразу поймём, что это так.
8:14
Тогда нам будет гораздо проще разбираться с растом. Дальше просто это надо выводить как как вот, ну, некий
8:20
базовый принцип. Это как бинарный поиск в алгоритмах. Вот такая вещь, я бы
8:28
сказал. Далее, второй вторая вещь, которую мы можем делать — это borrow.
8:35
вме вместо вместо это другой подход, когда мы хотим какую-то переменную, скажем так, куда-то передать, чтобы её
8:41
можно было прочитать, но при этом сохранить. Бору — это на самом деле ссылка. То есть мы передаём переменную в
8:47
данном случае мы во втором фрагменте Борову мы переменную А
8:52
инициализируем и передаём переменную B ссылку на неё. И переменная B имеет тип ссылки. Кстати, сразу скажу, чтобы вы
9:00
это, ну, не пугались. В расте не обязательно
9:05
объявлять, собственно, тип переменной. В большинстве случаев тип переменной определяется из выражение, из которого
9:11
она присваивается. Вот поэтому в большинстве случаев вы не увидите explicit declaration, но также можно объявлять
9:17
explicit, никто этого не запрещает. Вот. Но в данном случае вот ээ переменная B будет иметь тип ссылки
9:25
на strтринг. И здесь, обратите внимание, если мы тем не менее попытаемся
9:32
присвоить переменную переменную C в переменную C переменную А, мы должны
9:37
передвинуть её. Но А у нас заблокирована, потому что на неё есть ссылка действующая. Вот если мы это сделали, то
9:44
ссылка на А бы стала невалидной, но компилятор А этого не позволяет. C++ мы легко это сделаем. Мы потеряем ссылку. А
9:51
в Расте мы этого не сделаем. Сорри, у меня всё-таки сравнения, да, проскакивают вот с
9:56
другими языками, но я постараюсь минимизировать их. Вот поэтому, ну, опять же, вот там есть много разных
10:02
вариантов на эту тему, но если останется время, может быть, там можете вопросы задать, я расскажу
10:09
подробнее. И, наконец, самый лёгкий, но самый
10:14
затратный для памяти — это клонирование. Когда нам нужно переменную склонировать, мы просто должны
10:20
скажем так explicit, то есть
10:25
явно сказать, что мы присваиваем клон этой переменной. Тогда у нас, в общем-то, в данном случае переменная B —
10:32
это просто копия стринга А, и мы можем там дальше с переменной А делать всё,
10:37
что угодно. Она уже у нас отвязана. Вот ещё один важный момент —
10:43
это по умолчанию. Все переменные immutable. Я их не называю константами,
10:49
потому что constст — это другая парадигма, другой, в общем-то, оператор вра. Я скорее привык к
10:56
определению immutable. Вот. И чтобы переменную иметь возможность изменять, нужно её явно
11:02
объявить mutable, как в четвёртом фрагменте. Когда мы, допустим, объявляем
11:07
переменную mutable, мы можем её менять. Вот. То есть там производить
11:13
какие-то действия, менять всё содержимое. Вот. Но при этом интересный момент, что
11:19
если мы даём ссылку, mutable ссылку на mutable переменную, в данном случае
11:24
переменная B у нас это mutable ссылка, мы можем через переменную B менять содержимое переменной А, но при этом
11:30
любые другие ссылки становятся запрещены. Ну просто это такая вот такая вот изоляция эксклюзивный доступ. Если
11:37
мы дали эксклюзивный доступ, скажем так, по одной ссылке, по всем другим, другие ссылки мы делать не
11:43
можем, пока это пока скоуп действия вот этой ссылки
11:50
продолжается. Вот. Ладно, я бы мог ещё рассказывать, но, к сожалению, у нас уже вот время нас немножко поджимает. В
11:57
конце я могу ещё рассказать об этом. Вообще тема довольно
Traits
12:03
интересная. Так вот, теперь мы подходим к трейдсам. Самое интересное в Растве, вот их надо понимать изначально, чтобы,
12:09
в общем-то, ну, э, дальше легко и приятно программировать на языке. Значит, изначально, когда я
12:16
увидел, я подумал, — это то, что interfaces, однако это не совсем так. Дело в том, что interfaces в других
12:22
языках они optional. Мы можем их использовать, можем не использовать. Скажем, там, если мы используем базовые типы, мы можем прой
12:29
про про интерфейсы вообще не знать. А в Раст мы всё равно обязаны знать про интерфейсы.
12:36
Потому что, скажем так, все абсолютные типы, включая Basic, даже integers, они
12:43
используют trades изначально. То есть у нас есть огромное количество трейдс, то есть интерфейсов, которые объявлены в кор
12:51
языка, то есть как бы стандарт языка. Можно её можно, как говорится, как
12:56
C++ стандартная библиотека. Можно её это интерпретировать, но это опять же гораздо глубже. Это самый стандарт языка
13:02
присутствует. Там имеет огромное количество трейдсов. И даже все операторы, которые изначально
13:09
определены, они определяются от trades. Я, например, посмотрел, сколько
13:15
любой inteджер имплементирует трейдсов. Он имплементирует больше 400 трейсов. Вот я как увидел, немножечко
13:22
был в шоке. Но на самом деле всех их знать не
13:29
нужно. что приятно, что на самом деле нужно знать ровно те из них, которые мы хотим использовать. Вот, например,
13:35
примерчик, когда мы можем определить сложение на на нашей собственной структуре. То есть у нас есть структура,
13:40
в которой есть два интеджера. Вот uns inteне integer, и мы хотим там просто, ну, на ней определить
13:46
операцию сложения, так, чтобы у нас можно было при помощи знака плюс их складывать вместо перегруженных
13:53
операторов. Вот мы просто определяем стандартный трейд — это Crade AD. Это,
14:01
собственно, стандартный трейд, который объявлен в языке, который можно
14:06
определить для любой структуры. В данном случае мы определяем вот для этой структуры. Вот. И определяем его
14:13
функцию. Вот эта функция — это, в общем-то, его функция, которую, если определить, вот мы в ней можем как
14:19
угодно какие угодно операции производить и которые мы подразумеваем под сложение. В данном случае он просто складывает оба члены этой структуры. Потом мы можем там
14:27
объявить две переменные myтапы и просто их сложить и получим вот результат от
14:33
получим итоговый результат как структура, в которой оба члена сложены
14:38
друг с другом. Собственно, это очень похоже на перегрузку операторов, но, на
14:43
мой взгляд, сделано гораздо более, скажем так, универсально и понятно.
14:52
А также, а также вот весь язык он построен на трейдах. То есть там есть такие трейды, которые просто обязательно
14:58
определять для некоторых ну, скажем, собственных объектов, для того чтобы с ними можно было производить
15:05
операции, например, скажем, чтобы объект можно было клонировать или просто делать от
15:10
него, скажем, debгпint или передавать объект
15:16
между в параллелизме между потоками. Есть такие специальные, я сейчас на них
15:23
останавливаться не буду, есть специальные трейды, которые надо определять для этих объектов, чтобы это
15:29
делалось. Вот. Ну, также есть два способа: динамические и статические, это
15:35
ссылки на трейды, то есть их можно будет передавать как параметры функции, как или как generics. Вот я слишком подробно
15:41
останавливаться на этом, опять же, не буду, потому что это большая тема. И, наконец, объектная модель, которая в
Объектная модель
15:47
какой-то мере является продолжением темы трейтов частично. Значит, здесь ситуация
15:56
такая. ВАТ нет классов. Вместо этого мы отдельно определяем данные, то есть
16:02
структуры, и отдельно определяем их
16:08
имплементацию объектов, которые для этих данных. То есть в данном случае у нас структура MySC. И мы определяем две
16:16
функции. Функция new — это псевдоконструктор. В раз, кстати, нету конструкторов. Там принято делать
16:21
псевдоконструкторы, как функция new, которая просто создаёт новый новую
16:28
инстанкта. И там она может любой параметр принимать и, в общем-то, инициализировать объект, как хочет. Вот.
16:33
А также определяем функцию Make Copy. Ну, это наша функция, при помощи которой мы, допустим, его копируем.
16:40
Притом, значит, я использу использовал здесь Generic. Я заоду немножко про Generic расскажу на этом примере.
16:48
Как очищается память, если нет горбачколлектора? Ээ я расскажу после того, как мы закончим с базовыми
16:54
принципами. Напомните мне просто. Ээ, значит, здесь у нас, ээ, ээ,
17:02
видите, я определяю generic, то есть mystract типа t. Т у нас generic и
17:08
второй филд имеет типт здесь. И, соответственно, здесь я дальше
17:14
я, когда я определяю, я этот тип здесь указываю. Но обратите внимание, что здесь не просто им impм- это оператор
17:20
имплементации. То есть я говорю, что я имплементирую мою структуру дальше вот таким образом. И здесь я
17:27
говорю не просто т, а т клоу. Клоун в данном случае трейд. Это базовый, это
17:32
так встроенный трейд языка. Почему я обязан его определить? Потому что вот здесь вот для, скажем так, вот этого
17:39
типа я для копирования я использую его функцию clone. Это говорит о том, что только
17:46
типы, которые имеют трейк клон, определяют, имплементируют трейдклон,
17:52
могут быть использованы в качестве дженерика. Например, ну, tradeклон имеет подавляющее большинство типов по
17:59
умолчанию, например, скажем, тот же тот же стринг и так далее, они все имеют трейдклон. И, в общем-то, даже, ну,
18:07
большинство, подавляющее большинство, скажем так, кастомных типов, которые структуру вы определяете, там можно
18:14
определить для неё база дефолтную имплементацию клона при
18:20
помощи при помощи макросов. Но я здесь я макрос здесь не рассматриваю. Это, скажем так, можно воспринимать как
18:26
лёгкий способ определения стандарт стандартного определения некоторых системных
18:32
трейтов. Вот. Ну вот здесь главный момент.
18:37
Self — это, скажем так, селф с маленькой буквы — это копия
18:43
инстанса. Данная данной копия данного инстанца. В данном случае это структура майстрак. Копия её. Sell с большой буквы
18:50

это имя класса текущее. То есть в данном случае это имя класса Mystract. То есть различие в том, что селс большой
18:57
буквы это определение класса, и от него мы можем вызывать, скажем так, статические функции.
19:07
Ээ, да, конечно, Дима,
19:13
спасибо. Вот, ээ, я не очень понял вопрос про именно
19:19
такое имя нужно использовать, как этот тип, скажем так, можно использовать self. Вот, скажем, можно использовать
19:25
self в качестве типа сл с большой буквы, а можно использовать именно имя структуры. Можно и так, и так в этом
19:31
плане. Вот. Ну, на чём я остановился. Ах да. Значит,
19:37
здесь вот важный момент, то, что опять же дженерики у нас здесь ограничены тем,
19:44
что мы должны определить какие трейты они должны имплементировать. Таким образом, мы
19:50
опять же делаем safety. Вот проводим сейфти. То есть у нас только определённые типы могут сюда
19:57
быть переданы, которые имплементируют те функции, которые мы вызываем, в общем-то.
Параллелизм
20:05
Вот дальше про параллелизм я немножко расскажу. Значит, здесь у нас интересный момент, то, что
20:11
РАЗ поддерживает несколько моделей. Есть традиционная потоковая модель, когда мы
20:17
просто можем новые потоки создавать, там спаун делать. У нас просто создаётся новый поток, и как бы наша функция
20:25
запускается, да, наша функция запускается в новом потоке. Это традиционный подход. В общем-то, здесь
20:31
ничего нового нет, но интересно то, что, в общем-то, этот подход, он немного
20:38
дискорничит, потому что, скажем так, ну, понятно, что когда у нас слишком много потоков, переключение контекста начинает
20:45
занимать большое количество ресурсов. И, в общем-то, ну, ээ бенефиты потоковых
20:53
моделей становятся не столь не столь очевидными и, скажем так, исчезают.
21:01
Взамен этого расплагает так называемую асинхронную модель. При этом он оптимизирует ресурсы
21:08
и использует как потоки. То есть у него там есть некий внутренний пул потоков, оно количество потоков небольшое, но при
21:15
этом он старается использовать IDЛ время на других потоках. То есть, скажем так,
21:20
он может несколько процессов запустить на одном потоке, при этом используя IDЛ. То есть там, если у вас у нас очень
21:27
редко, скажем, один в реальной жизни, там, в реальном сервисе один, э, скажем так, одно флоу
21:34
работает постоянно с полной загрузкой, чаще всего оно имеет перерывы. Вот эти вот в эти перерывы он всовывает другие
21:39
флоу, то есть он экономит количество потоков и, соответственно, ээ в данном случае работает быстрее.
21:45
Конечно же, если у нас предположить, что каждый флоу работает с полной
21:51
с полной загрузкой, ээ тогда в этом случае, конечно, скорее
21:57
всего, нам нужно использовать традиционную модель, но чаще всего это на самом деле не так. Значит, там
22:03
был вопрос про Reactтив. Ээ можно немножечко его-то как бы расширить, потому что я не очень знаком с Reactтив
22:10
в данном случае. Это можно будет там, скажем, в конце более подробно вопрос расширить, тогда
22:16
мы можем побеседовать на эту тему.
22:22
Вот таким образом. Вот это одна вещь по поводу параллелизма интересная, то, что
22:27
вот я, например, использую так называемую модель ток
22:35
io. Это про Давайте проговорим про реактор позже немного. Вот немножко
22:40
более подробный вопрос. Вот. Потому что я, честно говоря, его в раз ещё не
22:46
использовал. Вот. Ээ, есть такая модель ToК io для серверной части. Она, в общем, довольно удобна именно в том
22:52
плане, что она полностью имплементирует вот именно такую асинхронную модель.
22:57
Допустим, когда мы пишем какой-то сервер, там RPC сервер, HTP сервер, Microsрвиice,
23:03
whatever. Очень это очень удобно, потому что вот именно он вот позволяет экономить
23:09
ресурсы. Ага, понятно. Concurrency model. Я немножко расскажу об этом.
23:15
Сейчас как раз concurrency model перейду. Значит, concurrency синхронизации на уровне данных. Вот
23:20
интересный момент здесь как раз как у нас стоят concurrenнcy. Опять же здесь вот то, что
23:26
я увидел в Раст, я никогда раньше не встречал. Мне это очень понравилось, то, что
23:32
синхронизация осуществляется на уровне данных. Вместо того, чтобы втыкать, скажем, мютексы, код и, скажем, какой-то
23:39
участок кода блокировать, он блокирует данные при помощи Мьютекса. Он оборачивает там любую, скажем, инстанс,
23:46
любую структуру, любую, скажем, данные в себя. Вот, например, в данном случае —
23:51
это обёртка. Это, скажем так, не некий объект, который блокирует,
23:57
скажем, не который блокирует точку входов в код, а он оборачива он это обёртка вокруг
24:02
данных. И таким образом, чтобы получить доступ к данных, нужно его завернуть. И при этом данные
24:08
блокируются. И после этого с данными можно делать всё, что угодно. При этом остальные flows, в общем-то, я не
24:15
называю это потоки, потому что не всегда это флоу — это поток. Остальные флоус ждут, пока, в общем-то, этот мтек не
24:23
освободится. Он освобождается, когда заканчивается с scope действия. То есть, когда мы выходим из функции или из
24:30
блока, тогда, в общем-то, мы освобождаем к тоже.
24:36
На самом деле подход довольно разумный, потому что он позволяет, например, получить эксклюзивный mutable доступ,
24:41
даже если сам Mutex не объявлен как mutable. Видите, тут просто объявлен как не как immutable. Но интересно, что
24:49
когда мы его разворачиваем, мы получаем доступ к переменной, можем отделить переменную mutable. И после этого мы можем уже
24:56
работать сable функциями, менять её как угодно. Это позволяет, на самом деле, одну и ту
25:04
же, один и тот же объект, одну и ту же, один и тот же инстанс раскидывают между различными flows, как угодно, и, в
25:10
общем-то, не боятся, что и в общем-то, если он навёрнут мс, можно дальше уже не бояться, что там будет какое-то
25:16
повреждение, к примеру. Притом интересный ещё момент в том, что
25:23
сознательно блокирует передачу необёрнутого объекта между между Flows.
25:30
То есть, например, спаун сделать на необёрнутый объект, который дальше используется как mutable хотя бы в одном
25:36
месте. Невозможно. Компилятор это заблокирует. То есть можно, скажем, это
25:42
делать для объекта, который immutable. То есть все имеют только доступ. Там это
25:47
можно делать. Но если хотя бы один flow получает mutable доступ, тогда мы должны
25:52
обязательно обернуть его изначально в muteex. В общем-то, это опять опять же
25:58
вот для но для об в большинстве случаев этого достаточно и мы не должны ничего другого
26:04
использовать. Опять же кс есть в разных моделях Мьютекса по-разному работает. Вот в ток i с моделью
26:11
ASIN он, в общем-то, работает. Это это асинхронная функция L. И она, в общем,
26:17
просто ждёт. Можно ждать, пока, собственно, ээ объект освободится и можно его будет
26:23
заблокировать. Скажем так, в традиционной потоковой модели там другой, который опять же работает ээ
26:32
который просто тупо, который тупо с блокировкой работает. То есть он блокирует код и либо там возвращается,
26:39
когда мюс заблокирован, либо возвращает ошибку. Скажем, если, ну, предыдущий поток с блокирующим Utex,
26:45
ээ, ээ, в нём произошёл паник, к примеру, это немножко это немножко другая модель. Вот я я, например,
26:53
предпочитаю использовать то io meex, если я в тоo работаю. Хотя,
26:58
например, вот, ну, просто я немного вперёд забегаю, в документации приветствуется
27:04
использование обычного Мьютекса. Якобы он работает быстрее. Опять же, я не проверял.
27:10
Вот это что касается, это интересный вот момент синхронизации. Мне лично это очень нравится в
Безопасность кода
27:17
Раст. Ну и чтобы резюмировать, безопасность осуществляется за счёт вот
27:22
некоторых вещей. Контроль памяти,
27:28
ээ, это вот то, что мы разбирали. Life мы его не касались, это отдельная тема
27:34
для разговора. Но в целом, например, скажем, если в како если у нас есть структура, в которой есть скажем так
27:41
какой-то член, ну, скажем так, член структуры, да, и мы хотим передать ссылку на него
27:48
куда-то ещё, мы просто так это сделать не можем, потому что структура может, скажем, если мы какую-то функцию
27:54
передать, структура может уже стать невалидной к тому моменту. Поэтому мы, это можно сделать, в принципе, при
27:59
помощи лайфтайма. То есть мы должны явно указывать лайфтайм для этой
28:05
структуры. Вот чтобы обозначить, что эта структура будет жива всё то время, в течение которого переданная ссылка там
28:13
где-то работает. Я сразу скажу, что эту вещь сложная. Я стараюсь этого избегать. Ну, просто потому, что это дополнительный dependences в код
28:19
добавляет. Но, э, в общем-то в целом это это сделать не позволено без лайфтайма.
28:26
Я так скажу, что вот нельз это невозможно сделать, чтобы передать, скажем, с
28:31
ссылку на структуру, которая умрёт раньше, чем ссылка будет доступна.
28:37
Вот это такой, я это воспринимаю как просто как гард. Ээ мт полей в структуре нету. Вся
28:45
структура может быть мтe. Тогда все её полят.
28:57
Вот. Ээ, ладно, Игорь, я думаю, мы можем это в конце более подробно рассмотреть.
29:04
Вот что конкретно вы имеете в виду. Я думаю, мы рассмотрим это было в
29:10
конце, потому что сейчас мы можем уйти слишком далеко. О’кей. Далее строгое соответствие типов. Ну, это, в принципе,
29:16
так во многих языках уже так типизованных языках.
29:21
Вот даже соответствие типов между вот uns интеджерами, например, просто
29:27
так сконвертить sign integer в негда можно далеко там, потому что если есть опасность оверфлоу, это сконвертить
29:35
нельзя, если не предпринять специальных действий для этого по умолчанию нельзя. И наконец синхронизация. Вот то,
29:42
что я обозначал, то, что объект, незащищённый мьютексом, нельзя просто так передавать ээ между
29:49
Flows, если он где-то получает, скажем так, ээ, read
29:57
доступ. И, наконец, несколько, ну, моментов, как стать растнженером, как
Как стать Rust-инженером
30:03
туда, в общем-то, войти. Нет, Моно и А я ещё не
30:09
использовал. Может, она более производительная. Вот я в конце, на самом деле, остановлюсь
30:15
немножко на этом на всём. Вот. Значит, какие трудности
30:21
вхождения? Значит, во-первых, понимание синтаксис. Если вы
30:26
взглянете на расткод первый раз, вы немножко придёте в шок, потому что там огромное количество дженериков, ээ, в
30:33
общем-то, различных, ээ, скажем так, различных вариантов, ээ, синтаксиса. раз
30:40
на самом деле очень гибкий в плане синтаксиса. То есть, допустим, где-то можно объявлять, где-то можно явно
30:45
объявлять тип переменной, где-то мы его объявляем по умолчанию, то есть когда
30:50
присваиваем. Вот, скажем так, те же коллекции, тот же вектор можно инициализировать несколькими
30:56
способами. Вот там имеется несколько синтаксисов для векторов, для слайсов, для массивов. Вот я на них сейчас
31:03
останавливаться не буду. Это большая тема. Вот. Но это немнож немножко может так поначалу быть непонятно с первого
31:10
взгляда на код. Вот понимано учить всё. Просто там фрагменты
31:16
кода рандомные смотреть, не понимая, что этот код делает. Это немножко бе, ну, я считаю, немножко бесполезно, потому что
31:23
очень много непонятного будет там, которые трудно, ну, трудно, скажем так,
31:28
сразу усвоить, понять, для чего вот это, а что вот это за конструкция. Например, та же имплементация, то, что
31:34
вот я показал немножко раньше, когда мы когда мы делаем имплементацию для структуры, есть минимум три способа её
31:42
сделать. Вот. И притом, скажем, если мы, скажем, имплементируем какой-то трейд
31:48
для структуры, есть два способа это сделать. Но синтаксис разный, и, скажем так, не всем будет понятно, что это, что
31:55
это имеется в виду, если мы не знаем вот что такое трейд, к примеру. Вот это первый момент, который, ну, немножко
32:02
напрягает новых разработчиков и немножко пугает их. Вот также, если нету опыта в других
32:09
языках, войти в раст немножко сложнее. Просто потому что на самом деле
32:16
вот для меня Раст, так я на него посмотрел, он просто попытался вобрать в себя все позитивные моменты от других
32:24
языков, которые, скажем так, есть. То есть, ээ, вы в нём найдёте от C++са и от
32:30
ГО, и от Джаваскрипта даже. Хотя, казалось бы, да, как казалось бы, что вообще между
32:35
Джаваскриптом и Растом? Однако можно найти там кое-что
32:42
схожее. Опять же, ну, легче учить раст тем, кто, например, все плюс-плюс имеет ээ вот опыт.
32:49
Ну, скажем так, даже я да со скала, наверное, я со скала
32:56
никогда не работал.
33:01
В общем-то, да, правильно подсказывают, что со скала тоже есть ээ много
33:08
параллелей.
33:13
Вот. Так что таким образом ээ здесь, в общем-то, рекомендуется, скажем так,
33:20
использовать предыдущий опыт или, ну, стараться вот понять вот эти базовые
33:25
принципы. Я для себя установил эти базовые принципы. Если их понять, даже не имея опыта работы в других языках,
33:31
можно на раз начинать программировать. Ещё важный момент, не надо стараться выучить всё.
33:37
Надо выучивать ровно то, чтобы достичь там конкретную цель задачи. Вот как, например, я сказал, там
33:43
Иджер имеет там 400 трейтов, но воще не обязательно их учить все. Можно вообще без них оходиться
33:49
поначалу. Или там, если вам надо переопределить, скажем, операцию плюс, достаточно один
33:57
знать. Вот. Дальше несколько советов разработчикам. Это, во-первых, учиться на примерах. Есть хороший ресурс Rust by
34:06
example. Вот рекомендуется его пройти. Вот там
34:13
вот именно очень хорошо
34:19
ложится. Вот дальше можно скажу, пытаться понять основные принципы языка
34:24
перед тем, как пытаться что-то писать. То есть понимать, скажем так,
34:30
как минимум модель памяти. Вот то, что я немножко рассматривал. Вот в это надо войти и
34:36
понять и начать решать практические задачи, собственно. То есть с простых примеров начинать, с простых задач
34:42
начинать писать код. В общем-то, тогда это можно будет войти
34:48
достаточно легко в это. Даже можно на лидкоде взять парочку простых задачек, попытаться что-то сделать. Уже немножко
34:56
можно начать понимать это всё. Вот. Ну, в общем-то, вот это всё, что я хотел сказать на сегодня.
35:04
К сожалению, за 40 минут можно было сказать ещё, что на 40 минут мы не уложимся в этом
35:10
плане. Ну и вывод насчёт того, что нужно ли переключаться на
35:15
раст. Во-первых, однозначного ответа нету на эту тему. Зависит от того, что вы хотите
35:22
достичь. Я скажу так, что если вы хотите писать что-то новое, что новый какой-то сервис с нуля, однозначно имеет смысл.
35:30
Ну, если вы ходите в блокчейн там, да, конечно, партировать существующие, я бы
35:37
поспорил, обязательно упрётесь в существующий дизайн, который надо будет переделывать. Это может оказаться
35:45
дорого. Там были была парочка вопросов на эту тему портирования. Я этого тоже коснусь, когда буду отвечать.
35:53
Так, ну что же, ээ, на самом
35:59
деле, да, про задачи, на которых подходит Раст, там на эту тему тоже есть вопрос в списке. Я
36:07
отвечу. Давайте к вопросам перейдём,
36:14
наверное. Так, ну, первый интересный вопрос — это какие в эти проблемы в Расты? Будут лини кто-нибудь закрыты?
Ответы на вопросы
36:19
Главная проблема, что раст язык молодой и ещё не до конца устоявшийся. Там есть,
36:25
скажем так, общие парадигмы, которые используются, но также есть и другие, о которых я не
36:31
упомянул. Это, так сказать, тёмная сторона, но, грубо говоря,
36:36
можно объявить блок кода и писать на нём как на C++ или даже на C с указателями,
36:42
со всеми прочими. Всё это есть, сразу скажу. Вот. Ну, это сделано для
36:49
портирования, скажем, существующих проектов, в общем-то. Если что касается меня, не
36:55
очень-то понимают, для чего это. Ну, потому что раз уже есть небезопасный код, зачем тратить ресурсы на
37:01
переписывание на другой язык, и код останется небезопасным.
37:08
Так что здесь вот, ну, это одно, это, так скажем,
37:14
ээ, та проблема, которая, скажем так, ну, есть. И вот, ну, как бы вот вот она она
37:22
закрыта вряд ли будет, потому что как бы ансей останется ансейфом. Вот другая проблема, на самом деле интересная, это
37:29
то, что есть огромное количество сырых библиотек. И, скажем так, для решения какой-то
37:35
задачи, если вы начнёте рыться на эту тему, вам выдастся очень много альтернатив, и вы вам потребуется
37:42
некоторое время, чтобы выбрать наиболее, скажем так, устойчиво. Вам ещё придётся покопаться там, чтобы найти, какая же из
37:48
них наиболее, скажем так, stable и какую лучше использовать, потому что, ну, как
37:54
бы, скажем так, очень очень много всяких подходов.
38:00
Так, промелькнул сейчас вопрос, касающийся освобождения памяти. Вот как правильно подсказывают.
38:07
На самом деле скажем так, это всё касается, ну, скажем так, скоупа. То
38:13
есть когда, допустим, если какая-то переменная объявлена в начале функции,
38:19
то, скажем так, она просто, ну, как бы она будет освобождена в конце функции, просто потому что она выходит
38:25
из скоупа. Если она объявлена в каком-то блоке, скажем, фигурных скобках, внутри блока, она освобождается по выходу из
38:34
блока. Вот. То есть как только она выходит из скоупа, где она может быть использована, она освобождается. То есть
38:40
просто как бы вызывается её деструктор. Там есть дроп, на самом деле, деструктор есть в расте, конструктора нет, а
38:47
деструктор есть. Он просто вызывается, как только переменная выходит из скоупа. Вот так происходит её освобождение.
38:57
Вот дальше по поводу Го и Раста. Вот этот вопрос опять же
39:02
интересный. На самом деле Раст очень некоторые вещи явно взял от Го.
39:07
Например, объектная модель очень похожа на Го. Она, конечно, в Раст расширена. В
39:12
Го она более простая, на мой взгляд. Что касается вопроса дополняющей или конкурирующей технологии, но я бы сказал
39:18
ни то, ни другое. Это просто два языка, и их оба можно использовать, ну, для аналогичных целей, я бы так
39:26
сказал. То есть, ээ, скажем вам там, если вам нужно написать ээ некий сервис,
39:32
ну, сервер там backend, и го и раз подойдут. Я бы сказал, что для в
39:39
некоторых вещах раст, ну, просто более продвинутый. Он, кажется, сложнее, но он просто, ну, именно в нём больше
39:46
возможностей. В го проще войти. Вот. Но в какой-то момент начинаешь ощущать потолок в некоторых вещах, а в
39:53
раз, ну, просто потолка не ощущаешь. Обязательно находишь что-то, что позволяет тебе решить
40:00
задачу. Вот как бы, ну, раст выглядит более продвинутым.
40:05
И ещё один момент, если действительно какие-то критичные к быстродействию или к памяти сервиса, скажем, код, скажем,
40:13
код, к примеру, да, я бы сказал, раз здесь предпочтительный, но просто потому, что в нём нет горобочколектора,
40:18
и он позволяет использовать память более тонко, действительно более так, ну,
40:25
в критических местах более экономно использовать
40:30
память. Вот, собственно, вот вот это вот краткое сравнение. Я бы мог об этом больше рассказать, но это обширная тема,
40:38
на самом деле. Например, вот скажем опять же в Go
40:43
Generics были добавлены очень недавно и до сих пор, ну, как бы они мне не очень
40:49
понятны. Вот так в раз я Gриic сразу понял, как они вообще работают и каков их принцип в
40:55
гонял. Может быть, просто не было времени этим заниматься. Так вот, по поводу перехода
41:02
с C++ на раз. Интересный на самом деле вопрос. Есть ли опыт перехода с плюс плюс на раз продуктах для HFT и
41:08
финансах? Может ли он купить затраты? Вопрос на самом деле очень абстрактный. Если существующие продукты задизайнены,
41:18
ээ, скажем так, не UNSAFE, у них нет ансайдизайна, тогда переход может быть очень затратным.
41:24
Проще просто новый, скажу, новую версию написать с нуля, чем портировать старую иногда.
41:30
Вот иногда опять же, но если там большой код, скажем, действительно много действительно много действительно
41:36
логики, то, ну, скажем так, просто портировать может быть сложно.
41:41
Обязательно можно упереться в какие-то вещи, которые позволены все плюс-плюс и легко делать, а в раз их просто, ну, раз
41:48
их просто блокируют и без редизайна их делать невозможно. И это может быть
41:54
действительно, скажем так, затратно с точки зрения ресурсов инженерных.
41:59
и может не окупить затраты. Но с другой стороны, может оказаться, что сервис
42:04
находится в таком состоянии, что количество багов, связанных с Unsafety, достаточно большое. Вот становится
42:11
ненадёжным тогда. Ну, приходится переписывать с нуля. Тогда раз имеет смысл, если редизайнить и переписывать с
42:19
нуля. Я бы так ответил. Вот следующий вопрос. Стоит ли
42:25
переходить на раз CDS C#ARP?
42:30
C#P для меня это язык, привязанный к Microsoft Стеку полностью, Microsoft
42:36
экосистеме. Я думаю, что в этом плане не стоит, я бы так ответил, потому что если
42:41
мы остаёмся на Майкрософте, как бы, ну, C#P он отлично интегрирован с майкрософтскими
42:47
продуктами и, ну, переход на раз, я просто не вижу в нём смысла в данном случае.
42:53
Если же мы что-то такое пишем Operation System Agnostic, то зачем нам C#ARP был
43:00
изначально? Так что я я бы сказал, что это просто у этих у этих, скажем так,
43:06
продуктов, у этих языков просто разные экосистемы, в которых они
43:14
работают. Так, по поводу компаний в Беларуси, которые использует трансфер разработки. Ну, наверное, есть. Я не в
43:19
курсе. Это, наверное, вопрос к инженерам из Белоруссии. Я просто насчёт того, что делается на
43:27
белорусском рынке, не в курсе. Я сам в Беларуси не живу. Так, насколько сложно в освоении
43:35
раз? Ну, сложности освоения я немножко затронул как раз ээ
43:41
в основном докладе. Да, может показаться
43:47
сложно, если не знаешь, скажем так, основных принципов. Для
43:54
я на скажум деле переходил с многих языков, из C++, из Goo и Джаваскрипта. Я не переходил, опять же,
44:00
я продолжаю на на джаваскрипте и на Go активно писать код, потому что у нас
44:07
продукты используют всё. Вот. Ну, скажем так, для тех, кто
44:13
знаком с Пплюсом, это несколько легче. Для тех, кто знаком с Го, тоже это встречаются знакомые конструкции. Вот
44:19
мне подсказали, что тот, кто скалой владеет, тоже будет просто. Тем, кто начинает с нуля, несколько сложнее. Но
44:26
опять же, если усвоить несколько принципов, которые я для себя, например,
44:31
обозначил, то это легче. Вот. Что касается экосистемы, я
44:37
опять же коснулся этого. Это блокчейн. То есть весь блокчейн он на раст
44:43
сейчас активно переходит. Вот новые продукты там пишутся на раст. Вот опять же ээс на салана тоже
44:53
раст. Да, совершенно верно. Есть опыт, если в разных парадигмах, то не очень сложно.
44:58
Да, совершенно верно. Ээ да. Так что, ээ, в общем-то,
45:05
ну, кроме того, э, сейчас активный раз начинается использоваться там в финансовых трейдинг, в трейдингсистемах
45:11
тоже начинает использоваться. Так что я думаю тоже туда можно заходить, смотреть там тоже
45:18
можно систему. Ой, что касается применения, где Раст
45:25
применяется. Так, про ресурсы для обучения раст я коснусь немножко дальше. Вот я в конце привёл пару ссылок.
45:33
немножко расскажу, как я изучал раст. Вот это будет отдельно, ну, это отдельный слайд у меня для этого будет в
45:39
конце в [музыка] самом поводу моего опыта с Раст. Значит,
45:48
у меня опыт меньше года. Я уже обозначился в самом начале, что, ну, моя
45:53
история такова, что мне нужно было войти в один блокчейстартап. Вот. Ну и для того,
46:00
чтобы там начать что-то там полезное делать, мне надо было как минимум знать Раст. Я начал его учить и, в общем,
46:08
начал начал работать над этим стартапом. Там писать так называемый
46:14
солвеers, это часть блокчейн инфраструктуры. Вот это сервисы,
46:19
которые, в общем-то, занимаются тем, что находят оптимальные параметры для транзакций на блокчейне в
46:27
целом. И в общем-то я начал писать proof of concepts. И в общем-то у меня начало
46:33
это получаться. Я так скажу, одновременно начал осваивать там раст конструкции, раст библиотеки,
46:40
там смотреть, какие HTTP сервисы там есть для этого, к примеру, там как сделать HTP клиента, HTP сервер, все
46:46
такие стандартные вещи. Вот как общаться с блокчейном. В Расте, кстати говоря,
46:53
мне показалось это гораздо более, скажем, логично и понятно, чем в Го.
47:01
И таким образом я начал это делать с другими языками, с теками. Как я уже сказал, у меня опыт около 20 лет, из них
47:08
17 лет в Гугле. Вот у меня есть опыт все плюс-польшой очень в Python, в Java
47:16
некоторый опыт есть. Ээ есть также опыт
47:22
в GO, довольно-таки такой обширный.
47:27
Вот. Но также с фронтендом у меня опыт JavaScriptм,
47:33
Typeesриптом. То есть у меня довольно большое количество стеков, в которых я работал. И в общем-то я могу сказать,
47:42
что, ну, я, в принципе, мне есть с чем сравнить Раст с другими
47:49
стеками. Что касается рынка труда, но здесь я, на самом деле, вряд ли могу что-то подсказать.
47:56
Скажем так, насчёт того, сложно ли найти работу, первую работу на раз, смотря где, и зависит от любую первую работу в
48:03
любом случае найти сложно. Нужно иметь некий, скажем так, некий бэкграунд и некий портфолио перед
48:09
тем, как вы найдёте первую работу. Это касается не обязательно раст, это касается любого любого стека, скажем
48:14
так, любой темы, что если есть некий опыт разработки, если есть рекомендации, уже некий референс есть от кого-то, это
48:22
проще, чем, скажем, э если просто с улицы приходить. Это от языка не зависит, я бы
48:30
сказал. Требование к кандидатам на раз, но ровно такое же, как ээ к кандидатам на любую любом другом стеке. Это скорее
48:38
касается, но опыта работы, что-то опыта завершённых разработок, getting things
48:44
done, работа в команде и прочее. Это уже, скажем так, не только, но и soft
48:50
skills. Вот я думаю, что если проект на C++, требования будут точно такие же, скажем так,
48:56
как и если проект нараст, требования к знанию языка. То есть нет ничего специфического насчёт раста, я не скажу.
49:05
Вот одна вещь, с которой я, кстати, столкнулся на эту тему вот недавно, это то, что, скажем так, если люди работают
49:11
в разных моделях, в разных, скажем так, в разных областях, то есть, скажем,
49:16
разработчики фронтенда, они не всегда могут понять разработчиков бэкэнда. Например, в Форхтене там используется
49:23
другая модель, скажем, та же ивент-модель, которая, скажем так, та же
49:28
ивент-модель параллелиизм, чем та, которая используется в бэкэндах. то, что вот я сказал Токио, да, там она другая и
49:35
сразу она непонятна, и там разработчики не всегда могут понять друг другу. Но это опять же нюансы
49:40
такие. Вот. Так что тут бы я бы сказал, что нету ничего
49:47
специфического. Вот. Ээ основная область применения раст или это уже многопрофильный язык, подходящий для
49:52
любых задач? Я бы сказал второе. Многопрофильный язык. Довольно обширное, скажем так,
49:58
количество библиотек довольно обширно и оно растёт. там количество фреймворков, с которым он
50:04
работает, он он тоже растёт. Опять же, я говорю, что не все из них stable, и надо
50:09
хорошо выбирать, прежде чем вы, допустим, собираетесь решать какую-то задачу. Надо просто выбрать, ну, скажем
50:14
так, наиболее стабильный из них, в котором наибо больше всего поддержка и, в общем-то, больше всего, ну, скажем
50:21
так, ну, имплементировано на нём. Тогда есть надежда,
50:26
что ваша имплементация, ваш ваш продукт будет
50:32
стабильным. Вот. Но опять же надо смотреть там, если вы работаете с центив информации, надо смотреть, что она через
50:38
эту библиотеку не утекает. Ээ можно так. Как дела с
50:43
бинарной совместимостью в библиотеке? Есть ли проблемы с конфликтом? Сейчас я посмотрю просто полностью вопрос. Одну
50:49
минуту. Есть ли проблемы с конфликтом зависимостей? Ээ, ну, скажем
50:57
так, я с этим ни разу не сталкивался. Может быть, есть, но я
51:02
скажу, что я с этим не
51:09
сталкивался. В целом же, ээ, что касается
51:14
ээ, скажем так, build общего общего, скажем, общего фреймворка для раст, он довольно-таки простой. То есть
51:21
карго более, скажем так, простого, интуитивно понятного фреймворка я не встречал. То есть, скажем,
51:27
сбилдить какой-то какой-то бинарник, там, скажем, добавить необходимые
51:32
библиотеки и сбилдить более просто, чем в карго. Я нигде это не встречал. Как сделать? То есть делается просто
51:43
элементарно. Вот. Ну, дальше давайте ещё у нас есть ещё несколько вопросов.
51:49
Значит, вот интересный вопрос по поводу Java и
51:55
Коotlн. Я бы сказал, что это разные сферы, то есть, ну, скажем так, котлин у
52:01
меня ассоциируется исключительно с андроидными мобильными приложениями. Конечно, я знаю, что это не так, но вот
52:07
у меня лично только такая ассоциация с ним. И здесь ну как бы котлин — это
52:12
котлин — это его сфера деятельности. Java — это Java, а Rast — это Rast. И нам он
52:20
совершенно отдельный. Я сказал, что, скажем так, на раз мне гораздо удобнее
52:25
разрабатывать, чем на Java и на котле. Но это, ну, я просто другие вещи разрабатываю. Вот если бы я, скажем, мне
52:32
нужно было бы разрабатывать андроидное приложение, я бы вряд ли его на разрабатывать. Я бы его на котлин разрабатывал. Хотя, честно говорю, мне
52:39
лично раз нравится гораздо больше. Что касается Java, опять же, если вам у
52:45
вас ваш дизайн построен на Dependency Ejection, то, в общем-то, раз тут не
52:51
подойдёт, тут нужна Java с его спрингом или там любым другим
52:57
фреймворком для Dependcy injection. depend injection, если вы его используете. Раз у него совершенно
53:04
другие принципы и dependent injection там просто нету. Поэтому, ну, я бы
53:09
сказал, что, э, в данном случае это вещи просто
53:14
работающие в разных сферах. Кто-то может меня опровергнуть, что типа на Java
53:20
можно делать всё, что угодно. Да, конечно, можно, но Garbage коллектор накладывает определённые ограничения. И
53:27
вот мне лично вот, ну, раз как-то ближе и понятней стал. Может быть, потому что
53:32
у меня большой опыт в C++. Java сравнительно небольшой опыт сравни с
53:37
C++. Вот я бы так ответил. Вопрос продолжения. В каких случаях есть смысл переписать Java
53:44
кодкод нараст? Если у вас написан какой-то сервис, который нуждается в быстродействии, и вам не нужен
53:51
dependency ejection в нём, тогда, конечно, либо можно переписать на раз, а вы выиграете.
53:57
Вот. И код станет более, скажем так, понятным, менее запутанным в итоге. Вот когда вы пройдёте через те,
54:05
скажем так, припоны на этапе компиляции, когда у вас какие-то вещи не будут
54:10
компилироваться, и вы это при помощи долгого, скажем так, компании в этом в итоге поборете и найдёте правильную
54:18
конструкцию, которая компилятор проглотит, дальше уже, ну, с большой вероятностью код будет работать
54:23
правильно. Вот. И в общем-то на этапе уже рантайма
54:29
у вас ошибки будут минимальными, хотя они, конечно, не исключены ни в одном языке. Даже в раст вы можете это
54:35
получить. Например, у меня была история, когда я умудрился устроить мерили league даже в
54:41
раст. Вот. Потому что, ну, собственно, ээ, я, ну, просто там есть
54:48
такая вещь, когда, ну, когда мы делаем спаун, можно, скажем так,
54:55
ээ, вразion Dependency Inversion. Я точно не
55:00
знаю, о чём идёт речь в данном случае. Вот я знаю, что такое
55:05
depend. Я не знаю, что такое, честно говоря. Никогда не сталкивался.
55:13
Значит, что касается дебагнга, скажем так,
55:18
сам по себе дебагинг он долгий пристальный взгляд,
55:27
да, дебагн — это долгий пристальный взгляд, в общем-то, и трейсинг в основном. То есть какого-то специфического дебагинга я не использую
55:34
просто. Но в Раст есть одна очень хорошая, на мой взгляд, удобная вещь.
55:40
Это, скажем так, assistants, то есть, скажем так, у него встроенный, скажем
55:46
так, это H compiler то, что называется, да? То есть, когда вы, скажем, в том же W
55:52
Studio Cд пишете код, и у вас работает ваш extension Rust extension, он вам
55:59
подсказку даёт тут же. Вы понимаете, где что у вас работать будет, а что не будет. Он, конечно, не всегда срабатывает, но вот это хорошая
56:06
подсказка. Вот. А так, в принципе, в основном, debug tracing.
56:14
Вот наверняка дебагеры есть, но я я просто вообще работаю несколько олдскульно в этом плане. Я пользуюсь дебагрейтингом,
56:21
поэтому, ну, мне не очень ээ это актуально. Я я не очень сильно
56:27
исследовал эту тему. Насчёт ID я ничего не могу сказать. Я её
56:34
не использую. Я использую минимально Visual Studio CД.
56:42
Вот это что касается вот Java Java котлина и перевода наст. Но
56:49
опять же, если у вас специфические, скажем так, сферы, конечно же, никто наст не
56:55
знаю. На Андроиде, на самом деле, ээ вряд ли кто-то будет писать на раз.
57:01
Хотя, может, потом и будут, я не знаю. Кстати сказать, Свифт для очень похож в
57:06
чём-то на раст. Там очень многие парадигмы там схожи. На самом деле это Swift взял
57:13
отраст. Значит, насчёт динамической памяти вопрос хороший. Значит, по умолчанию, э, память
57:22
в общем-то динамическая. Более того, там есть указатели со
57:29
счётчиками ссылок, но опять же, скажем так, скоуп
57:35
строго отслеживается. То есть пока у нас скажем объект находится в
57:42
скоупе, он, собственно, он действует, но как только выходит из скоупа, вызывается его
57:48
деструктор, объект уничтожается. Вот. Или, скажем, если мы оборачиваем
57:54
вреounter объекты refunter, тогда он, собственно, можем его раздавать как
58:00
угодно. И, собственно, он уничтожается, как только каounter уходит в ноль. Как только каounter у нас уходит из всех
58:05
скопов, объект уничтожается. Так что ответ, что память динамическая
58:12
дефолт. Вот. Но когда мы, собственно, это делаем, то есть там есть, конечно, часть, когда мы можем делать меморило,
58:19
мало делать даже. Ну какой смысл использовать это вра в расти? Я не очень понимаю. Может быть,
58:25
для каких-то фанатов все плюс-плюса имеет
58:31
смысл. Вот вот вопрос, на который я вряд ли
58:39
отвечу. Ээ, наверное, может быть, что-то и может. Я с этим не сталкивался. Касается поддержки машин лёнга и квантум
58:46
компьютинга. Я скажу так, что я с этим не сталкивался
58:52
попросту, так что вряд ли я отвечу на этот вопрос. Вот, собственно, вот список
58:59
вопросов, который у нас был. И у нас есть время ещё для
59:09
вопросов. Ээ, насчёт совместимости, в смысле, можно ли библиотеки из CC++
59:14
использовать в Раст. Я это я этого никогда не делал. наверное,
59:20
можно. Но в целом языки достаточно совместимы по парадигмам, по конструкциям, но не по дизайну, опять
59:27
же. То есть, если портировать коды, если что касается портирования
59:34
кода, та сейчас про ссылку отвечу. Если касается, что касается партирования
59:39
кода, как я уже говорил, обязательно можно нарваться на unsave конструкцию, которую придётся передизайнить, чтобы на
59:46
разделать. Что касается возвращения ссылки из объекта, нет,
59:51
нельзя. Можно вернуть сам объект. Но, собственно, то, что называется copy
59:57
elision в расте это работает изначально в модели. То есть, собственно, если объект
1:00:02
возвращается из функции, то тогда он просто, скажем так, ээ, ну, тогда он
1:00:09
просто весь объект возвращается, и тебе просто функцию больше не нужна. Это очень естественно для раст.
1:00:15
Ээ, сейчас отвечу на оба эти вопроса. Значит, первый вопрос сейчас одну минуту. Тут несколько вопросов
1:00:21
поступило. Сейчас открою ээ чатик. Ага. Значит, итого раз только
1:00:28
для блокчей. Нет, не только. Абсолютно для любых сервисов, скажем так, ээ, в
1:00:33
трендинге, в финансах, пожалуйста, его уже используют. Вот когда сталкивался с использованием РАТ во фронтде, там, где
1:00:40
есть криптография на фронтде, там его тоже используют уже. То есть где
1:00:46
угодно в блокчейне это просто необходимость. Там без раста делать нечего. В други в других
1:00:51
областях раз тоже используют. Какой мой следующий язык? Не
1:00:57
знаю, будет зависеть. Так, насколько легко вызвать
1:01:04
сишный код и насколько легко из сишного кода вызвать код на раз? Не пробовал, сразу скажу.
1:01:11
На самом деле я не очень большой фанат вот этих вот кроссвызовов. Вот наверняка можно это
1:01:18
сделать, но опять же тут мы сталкиваемся то, что сишный код может оказаться небезопасным. Он может в итоге вызвать
1:01:25
паник в нашем расткоде. Так что я был очень осторожен на эту
1:01:31
тему. Можно ли определить трейд для сорт пати структуры в каком-то своём скоупе?
1:01:39
Если эта структура, собственно, паблик и есть доступ, почему бы
1:01:49
нет? Вот, собственно, краткий
1:01:57
ответ. Какие-то ещё вопросы есть? А, голосом можно? Что?
1:02:06
Да. Вот мне интересно. Всё-таки тема с трейсами. Возможно ли их
1:02:12
делатьation? То есть как бы условно, если у меня есть структура, я знаю имена
1:02:17
полей. И каждая из этих полей я у него условно есть трейд Jonek или Jon
1:02:23
Encoder, допустим, да? Могу ли я написать какой-то для любой структуры, у
1:02:30
которой для каждого поля есть свой условный
1:02:36
энкоodдер? Вывести энкоodдер для всей структуры. Ну, потому что я знаю, как
1:02:41
называется поле. Я знаю, что поле точно имеет там э свой энкодер какой-то, да. Я
1:02:50
просто для меня параллель очень сильная с тейп-классами. Вот видите, как есть
1:02:56
трейд. Значит, сразу скажу, что наверняка вы просто говорите о
1:03:01
структуре, в которой каждый её член, это, скажем так, это
1:03:09
трейд. То есть либо это dмиic указатель на трейд, либо это трейд определённый
1:03:15
через Generic. Вот. У меня на самом деле вопрос, ну, не до конца понятен.
1:03:22
Вот я просто, о’кей, сознаюсь, я из вот со скала как раз нашёл параллели. Ну, я
1:03:30
на ней пишу, и там есть чудесная вещь, которая отличает её от других языков, но
1:03:35
из тех, которые я знаю, раз просто вообще не знаю, но вижу хорошие вещи в нём очень. Вот.
1:03:44
А это возможность вот эти вот эти, так сказать, условные трейты, как как в
1:03:51
Расте, да? То есть это так выводить интерфейс для добавлять действия в типу,
1:03:57
да, и объявлять их в скоупе. Возможность — это делать правила для этого. Ну,
1:04:03
условно если я знаю, э, мм, то есть трейд он чётко привязан к
1:04:09
какой-то структуре. Я не могу сделать трейд любого типа, не знаю, для для
1:04:17
любого для любой трейд к трейд к структурам не привязан. Трейд — это
1:04:22
просто, скажем так, совокупность функций, которая определяет
1:04:29
функциональность данного трейта. Да, Дмитрий, свои трейды, конечно,
1:04:35
делать можно и нужно. Собственно, раз на этом построим, что мы делаем свои трейды, а потом их, в
1:04:41
общем-то, имплементируем. Тут в этом плане, да, я имею интерфейсами. Я я
1:04:47
понял, в чём я ошибся. Я имел в виду, можно ли сделать имплемен имплементацию
1:04:52
трейта, э, потребовав, например, можно ли сделать общую generнеic имплементацию
1:04:58
трейда для любой структуры, для которой известны имплементации трейтов на каждое
1:05:05
поле. Вот так. Я не вижу вообще связи. Можно имплементацию трейта сделать для любого для любого абсолютно для любого,
1:05:12
скажем так, для любой структуры данных. Да, ладно, давай возьмёмте, давайте возьмём пару, где есть тип first а и
1:05:21
second b, то есть а и b — это generity, да. Да.
1:05:26
И я хочу ээ сдела вывести трейд допустим,
1:05:34
условный joncoder, если у меня joncoder есть для а и для b, вот такое я могу сделать.
1:05:43
Так, ээ, ну, собственно, если, скажем так, и А, и B имплементируют трейдкодер,
1:05:51
ээ, скажем так, да, это можно. А если для какого-то типа Б, допустим, у меня
1:05:57
не будет кодека, могу я эту структуру использовать, но просто без тех функций,
1:06:04
которые мне нужны для Жисона. Но придётся их имплементировать в вашей имплементации. То есть у меня
1:06:11
трейд жёст жёстко ограничивает все мои использованные структуры, не только даже
1:06:17
не связанные с функциями самого трейта. Ээ не обязательно. То есть
1:06:22
главное, если для структуры имплементируется трейд, вы просто должны имплементировать ээ функции этого
1:06:29
трейда. Всё. Как вы их имплементируете, уже никого не как бы сам трейд не волнует. Это зависит от вашей
1:06:35
функциональности. И я задавал в чате этот вопрос просто и
1:06:40
вы пропустили. Если вот более простой пример, если у меня вы приводили пример с clonable, да, что вот есть у него есть
1:06:48
T и T clonable, это значит, что T всегда должен быть clonable, если
1:06:53
я хочу эту структуру или в том случае Ага, понятно. Просто он должен быть
1:06:58
clonable, если вы у него, допустим, клон вызываете, просто должен ориентировать clonable. То есть я я могу определить
1:07:05
этот трейд вот как он у вас определён, но при этом в каком-то месте кода мне
1:07:12
мне нужен майстракт с условным фубаром, который не клона. Я я и не собираюсь его
1:07:18
клонировать. Я просто хочу вот ту же самую структуру использовать. Я смогу её использовать или трейд, который объявлен, он жёстко
1:07:26
даёт ограничение. Значит, тут ситуация такая. Если вы у этого члена не будете вызывать клон, то,
1:07:33
в принципе, вам не нужен clonable здесь. Если вы увидели в моём примере, там явный вызов функции клон у члена
1:07:39
функции. Да, ну, ну это же трейд. Ээ м просто я просто пытаюсь понять ваш
1:07:49
вопрос. Если вы можете определить любой трейд для любой функции, вы можете при этом, ну, скажем так,
1:07:54
вызывать ээ ээ это всё для, скажем так, для каждого члена, если
1:08:02
это определено, или просто написать самому. Это, как говорится, ну, на ваше усмотрение. Кстати, я забыл
1:08:08
переключиться на последний слайд. Вот, ээ, это те ресурсы, которые я могу, с
1:08:13
которых я могу порекомендовать начать изучение языка. Вот. Иван, возвращаясь к вашему
1:08:19
вопросу, ну, здесь как бы на самом деле вот я скажу так, что если у вас каждый
1:08:25
член структуры определяет какой-то интерфейс, то в этом случае можно облегчённым
1:08:32
образом определить, э, скажем так, трейд для всей структуры. То есть там есть такая вещь,
1:08:38
как его можно определить через макро. Ага. Всё понятно. Если делается через макро, да, это делается через макро, да.
1:08:44
Вот в этом случае это можно, если это всё, всё определено для каждого члена. Но если нет, тогда придётся вручную
1:08:50
определять, собственно, имплементировать этот трейд для структуры, и тогда уже вы должны сами там писать этот код, который
1:08:56
у вас будет делать что-то кастомное. Ну, я правильно понял, что мы определяем для вот нашей структуры трейд, то есть мы
1:09:02
говорим, что вот эта структура этот трейд имплементирует, э-э, скажем так, Generнериic в этой
1:09:09
структуре приметирует трейд в том примере, в который я приводил. Сама структура его не Я понял, да? Да, да, да. А, но мы можем делать вывод трейтов,
1:09:17
то есть сказать, что если если в структуре поле clonable, то и для всей структуры имплементирован clonable. Вот
1:09:25
если все поля clonable, мы можем, да, легко там через макро определить, что клонаable для всей структуры. Ну и если
1:09:31
хотя бы для одного он не клонаable, тогда сами, то есть делать свою имплементацию уже,
1:09:37
да. Но это не обязывает нас всегда использовать clonable в этой структуре. Мы можем использовать эту же самую
1:09:44
структуру, но просто трейд будет недоступен, если у нас generic не clна. Верно? Да, это не обязательно. Это не
1:09:51
обязательно. Опять же, что если мы клон не вызываем у него, зачем нам клонаable? Вот так. То есть в одном месте это же
1:09:58
Generриic, в одном месте мы вызываем, в другом не вызываем. То есть с с одним та пора дженерика его вызываем. Я так
1:10:03
скажу, если мы у дженерика его вызываем, значит, он должен вызываться у любой имплементации этого дженерика. Тогда нам
1:10:10
действительно нужно сказать, что он clonable. Вот так вот такая тут система, как бы. То есть мы ровно то, что мы
1:10:17
используем, мы должны сказать, мы должны ээ определить. То есть тут вот такая такой
1:10:26
подход. Вот. Ну, в общем-то, мы плавно-плавно подошли к концу. Вот. Ээ всем большое спасибо за
1:10:34
внимание. И в общем-то мой мой следующий, на самом
1:10:40
деле, этап — это я готовлю более, скажем так, продвинутый взгляд на раст и, в
1:10:46
общем-то, скажем так, готовлю крэш-курс. Если кого-то заинтересует, то просьба
1:10:52
через сообщество, ну, выразить интерес к этому. Я тогда более интенсивно этим займусь и уже могу представить
1:10:58
какой-нибудь уже более подробный, скажем так, смотреть какой-нибудь подробные проблемы и уже переходить к, в общем-то,
1:11:06
обучению, если будет
1:11:13
интересно. Да, ещё был вопрос про ООП. Собственно,
1:11:19
ээ, скажем так, это не классический ООП. Вот в том плане, как то есть объектов
1:11:24
как таковых там нету. То есть как бы мы привыкли к классам, да, когда у нас, скажем так,
1:11:32
имеется наследование, ээ полиморфизм и, ээ, кстати, хорошая идея
1:11:39
начат открыть курс, скажем так. Какие ещё там были у
1:11:44
нас принципы? А, инкапсуляция, наследование, полиморфизм — это старые принципы ООП. Наследования враст вообще
1:11:50
нету никакого. Полиморфизм, собственно, есть через трейты, вот через дженерики. Это это,
1:11:57
собственно, полиморфизм. Вот. А что касается инкапсуляции, то, ну да, можно сказать,
1:12:03
тоже он есть. В эплемитации трейна можно сделать инкапсуляцию.
1:12:09
Собственно, вот это я это вижу так.
1:12:22
Вот есть ещё какие-то вопросы в
1:12:31
догонку? Хорошо, ребята, всем большое спасибо за внимание. Было, на самом деле, очень приятно
1:12:37
ээ читать делиться своими мыслями с вами. Чувствуется, чувствуется на самом деле,
1:12:45
скажем так, фидбек, обратная связь. Очень чувствуется. Очень приятная
1:12:50
аудитория. Спасибо всем большое. Мне было очень приятно. Yeah.

Поделиться: