Ёлки-палки, чего ж вы все такие крутые сишники паритесь и, простите, на говно-то исходите? Я, конечно, нарываюсь на минуса в карму, но что ж вам так раст покоя не даёт? Ну не нравится он вам, не видите в нём смысла, но вас же никто не заставляет силком на него переходить! Если он вам так не нужен, что вы забыли в этом и аналогичных топиках? Вот вам этот языке не нужен и не нравится, а другим людям нужен и нравится. Ну так и пройдите себе мимо! Зачем и себе и другим нервы трепать? Вот нравится некоторым фигнёй с никому не нужными языками страдать, ну так а вас это как касается? Вас что, глубоко раздражает, что кто-то пишет не на Си++? Почему вы на питонщиков тех же так не наезжаете? Ведь си же круче!
1. При динамической диспетчеризации и идёт ссылка на экземпляр в самом методе, &self и есть такая ссылка.
При статической диспетчеризации никаких «таблиц» нет в принципе. Я не понимаю вопроса. Варианта два: либо есть таблица виртуальных методов, и в вызванный метод отдаётся ссылка на экземпляр типа через &self, либо нет таблицы, есть статический вызов метода, но в него всё равно передаётся та же самая ссылка на экземпляр типа &self. Всё происходит прозрачно.
Как ни вызывай, в &self будет ссылка на конкретный экземпляр типа, на котором вызывается метод.
Если в типаже есть методы, принимающие self по значению, то этот типаж не объектнобезопасен, так что нет, в случае динамической диспетчеризации по значению экземпляр в метод передать нельзя.
2. Нет, нельзя. Два раза один и тот же типаж для одного и того же типа реализовать нельзя, иначе непонятно, что к чему относится.
1. Вид диспетчеризации зависит от использования типажа. Если типаж используется как баундинг на типовый параметр, то будет специализация и статическая диспетчеризация (это в расте называется «мономорфизация»), если используется «ссылка на типаж», то будет создан типаж-объект и будет динамическая диспетчеризация.
Всё зависит только от того, как типаж используется, а не от того, как объявляется.
Другое дело, что некоторые типажи не являются «объектнобезопасными», и использовать их как типажи-объекты нельзя.
Но это отдельная тема.
Надеюсь, я ответил на вопрос.
2. Не совсем понял вопрос, попробую ответить развёрнуто.
а) Чтобы реализовать типаж для типа, нужно, чтобы или типаж, или тип был объявлен в текущем крейте.
Если оба они в чужих крейтах, то компилятор не даст реализовать этот типаж для этого типа.
б) В пределах одного крейта, если имеется в виду один и тот же типаж для одного и того же типа, то может
быть только одна такая реализация, иначе будет конфликт реализаций: is.gd/S1FCmO.
в) Если трейт объявлен с одним и тем же именем и одними и теми же методами в разных модулях одного крейта,
то это де факте два разных типажа, и да, их можно оба реализовать для одного и того же типа, и подключать какой-то
из них выборочно: is.gd/QJWLkc.
Но оба таких типажа из разных модулей подключить просто так нельзя, т.к. будет конфликт имён.
Можно заюзать форму use modb::A as A1, но тогда всё равно нельзя будет использовать
метод типажа обычным образом, т.к. не ясно, от какого типажа метод использовать (error: multiple applicable methods in scope).
Надо будет вызывать метод через UFCS: is.gd/LTfXcZ
Подозреваю, что вопрос риторический, но всё же отвечу =)
Эта функция с побочными эффектами.
Но эта функция не проходит критерий «не меняет данные, находящиеся вне функции».
Потому, что она меняет состояние дескриптора стандартного вывода, который находится вне этой функции.
Так что всё правильно написал автор.
Рекурсия хорошо работает в тех языках, где компилятор её хорошо оптимизирует (через оптимизацию хвостовой рекурсии). В питоне этой оптимизации нет (по крайней мере в CPython), так что я бы не стал перебарщивать с рекурсией в питоне, но в том же луа или хаскеле — это вполне нормальное решение.
Эта проблема частично нивелируется с помощью пайплайнов, которые описаны в статье. Но в общем случае да, проблема есть, но она решается в функциональных языках различными методами, с помощью комбинаторов, композиций и т.п. Тема отдельная, нужно погружаться глубже, сейчас на это нет времени подробно расписывать, но по ключевым словам можно гуглить дальше.
Однако согласитесь, что по крайней мере сейчас он лучше, чем C++. Кроме того, меня уже немного достаёт, что его только с плюсами и сравнивают, это не совсем справедливо, ведь язык волне сопоставим и с питоном (по уровню абстракций), и со скалой/явой, он вполне может конкурировать со многими высокоуровневыми языками.
И не мне, и не вам судить, что будет через н лет, мы не провидцы.
А если его никак не продвигать, то прогресса не будет, не будет ничего лучшего на замену плюсам.
Во-первых все строки на расте в utf-8. По поводу memcpy и memset париться обычно не нужно: раст не даёт использовать неинициализированные переменные (это ошибка компиляции), а значения типов, поддерживающие копирование (реализующие трейт Copy), копируются автоматически. Не копируемые значения перемещаются де факте тоже копированием, но только при передаче за пределы функции, а уже перемещённые значения использовать нельзя, компилятор не даст.
Без стандартной либы жить можно. Можно посмотреть на rustboot для примера. Можно выключить stdlib и оставить только core, тогда будет доступ к самой низкоуровневой функциональности.
В общем, нет, нельзя.
&self
и есть такая ссылка.При статической диспетчеризации никаких «таблиц» нет в принципе. Я не понимаю вопроса. Варианта два: либо есть таблица виртуальных методов, и в вызванный метод отдаётся ссылка на экземпляр типа через
&self
, либо нет таблицы, есть статический вызов метода, но в него всё равно передаётся та же самая ссылка на экземпляр типа&self
. Всё происходит прозрачно.Как ни вызывай, в
&self
будет ссылка на конкретный экземпляр типа, на котором вызывается метод.Если в типаже есть методы, принимающие self по значению, то этот типаж не объектнобезопасен, так что нет, в случае динамической диспетчеризации по значению экземпляр в метод передать нельзя.
2. Нет, нельзя. Два раза один и тот же типаж для одного и того же типа реализовать нельзя, иначе непонятно, что к чему относится.
Всё зависит только от того, как типаж используется, а не от того, как объявляется.
Другое дело, что некоторые типажи не являются «объектнобезопасными», и использовать их как типажи-объекты нельзя.
Но это отдельная тема.
Надеюсь, я ответил на вопрос.
2. Не совсем понял вопрос, попробую ответить развёрнуто.
а) Чтобы реализовать типаж для типа, нужно, чтобы или типаж, или тип был объявлен в текущем крейте.
Если оба они в чужих крейтах, то компилятор не даст реализовать этот типаж для этого типа.
б) В пределах одного крейта, если имеется в виду один и тот же типаж для одного и того же типа, то может
быть только одна такая реализация, иначе будет конфликт реализаций: is.gd/S1FCmO.
в) Если трейт объявлен с одним и тем же именем и одними и теми же методами в разных модулях одного крейта,
то это де факте два разных типажа, и да, их можно оба реализовать для одного и того же типа, и подключать какой-то
из них выборочно: is.gd/QJWLkc.
Но оба таких типажа из разных модулей подключить просто так нельзя, т.к. будет конфликт имён.
Можно заюзать форму
use modb::A as A1
, но тогда всё равно нельзя будет использоватьметод типажа обычным образом, т.к. не ясно, от какого типажа метод использовать (
error: multiple applicable methods in scope
).Надо будет вызывать метод через UFCS: is.gd/LTfXcZ
3. Да, конечно можете.
Эта функция с побочными эффектами.
Но эта функция не проходит критерий «не меняет данные, находящиеся вне функции».
Потому, что она меняет состояние дескриптора стандартного вывода, который находится вне этой функции.
Так что всё правильно написал автор.
И не мне, и не вам судить, что будет через н лет, мы не провидцы.
А если его никак не продвигать, то прогресса не будет, не будет ничего лучшего на замену плюсам.
Без стандартной либы жить можно. Можно посмотреть на rustboot для примера. Можно выключить stdlib и оставить только core, тогда будет доступ к самой низкоуровневой функциональности.