Pull to refresh
@math_coderread⁠-⁠only

User

Send message

Идеология разная. В случае C# есть контекст, где использовать unsafe нельзя, в случае Rust такого нет. То есть в C# разделение на safe и unsafe используется для безопасности, а в Rust — исключительно для удобства программиста.

Arc не отвечает за синхронизацию доступа к объекту между потоками, а только за его удаление.

Это детали. Может не Arc, а Mutex<Arc> или ещё что-то такое.


Управляемый объект может быть организован так, что операции над ним потокобезопасны (например, обертка над библиотечным).

Да, может. И в случае именно Rust от такого объекта ожидается, что эта его потокобезопасность будет выражена в API этого объекта. Потому что Rust содержит необходимые средства для этого. Если API объекта не сообщает компилятору, что его можно свободно мутировать, то вам придётся сделать над объектом обёртку с unsafe кодом. И дальше вы сможете работать с объектом через эту обёртку без обращения к unsafe.

Если у вас многопоточное приложение, то каким-то образом вы должны синхронизировать потоки. Именно это и делает Arc, так что это, вообще говоря, не оверхед, а необходимая функциональность. Если же у вас какой-то свой хитрый способ синхронизации, то стоит подумать о передекомпозиции таким образом, чтобы явно выделить эту синхронизацию и инкапсулировать в неё unsafeы.

Это известный миф про Rust. Рациональная основа мифа состоит в том, что некоторые структуры данных, например, двусвязный список, проблематично реализовать без использования unsafe.


Иррациональная же (собственно мифологическая) часть — это то, что если вы в Rust-программе использовали unsafe, то это, якобы, неправильно. Возможно, играет роль схожесть ключевого слова с unsafe C#/.NET, которое и в самом деле является не столько частью языка/платормы, сколько расширением, и по-умолчанию недоступно.


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

Да, и это очень круто, что Rust ловит такие вещи на этапе компиляции — с этим спорить сложно.

Нет, в C# lock мне писать бы вообще не пришлось. В смысле я бы скорее всего вообще не сообразил, что он нужен. Получился бы ошибочный, но короткий код, при этом ошибка в реальности воспроизводилась бы редко, а то и вообще никогда.


если b() вернет null, то вы получите NullReferenceException в рантайме

Всё правильно, там и должен быть NullReferenceException. В чём ошибка?

Что-то больно у вас легко всё.


  1. Пробовали ли вы написать на Rust функцию, которая принимает функцию, которая принимает функцию? И чтобы первая функция упаковывала переданную ей функцию вглубь структуры данных для последующего неоднократного коллбэка. И потом вызвать всё это с хитрыми замыканиями. Я пробовал, и код получается весьма перегруженный лайфтаймами и тому подобным. Не скажу, что результат неприемлем — совсем нет — но достаточно громоздок, чтобы начать избегать передавать функции в функции.


  2. Использовали ли вы RefCell? А Mutex? А Mutex<RefCell>? А сочетание всего этого с Option? Код, который в C# или там Python выглядел бы как a.b().c начинает выглядеть примерно как a.lock().unwrap().b().as_ref().unwrap().c



На Rust действительно приятно писать код. Он действительно является привильно сделанным Си. Это всё правда. Но если вы можете конкретную штуку написать на чём-то другом — ну, например, F# — лучше писать на другом. Возможно, вы получите меньше удовольствия, но код точно будет существенно короче.

> Короче, долгая, нудная и часто неблагодарная работа.

И предлагается сделать её ещё более нудной? (По-моему, тест и вообще код, содержащий конкретные значения вроде `2`, `'a'`, `«Dr. Jones»` наконец, гораздо менее нудный, чем не содержащий таковых.)
Только ведь ваша «единственная аксиома» — это не аксиома, а схема аксиом, а аксиом получается счётное количество при любом конечном количестве схем.

Что это антипаттерн, и что в современном C# есть средства получше. Конечно, в public API нужно использовать хотя бы и антипаттерн, если это именно то, чего ждут пользователи этого API.


Но за исключением указанной выше ситуации вместо IDisposable лучше просто сделать метод Dispose(), а лучше метод с более конкретным названием. Не знаю, стоит ли такое упоминать, но класс должен быть sealed.


Конечно, раз уж мы сделали класс sealed и всегда зовём Dispose() явно, не полагаясь на финалайзер, то можно и : IDisposable подписать — просто чтобы использовать using. Но тогда появляется соблазн прикастить его где-нибудь к IDisposable, вернувшись таким образом к антипаттерну, а using на самом деле прекрасно заменяется на статический метод вроде T With<T>(Func<MyDisposableClass, T>), причём в некоторых случаях можно даже скрыть конструктор класса, оставив только этот метод.


А в некоторых случаях можно пойти ещё дальше, и вообще избавиться от класса, оставив только функцию With, которая будет выглядеть как-то так: T With<T>(Func<Resource1, Resource2, Resource3, T>)

> Упс! Я не могу правильно реализовать IDisposable без гугла.

Реализовывать IDisposable без гугла — это уровень джуниора. Миддлу неплохо бы понимать, что IDisposable реализовывать вообще не надо.
> Но это не их проблема — их не для этого делали.

Естественно, это не их проблема. Это _моя_ проблема. Но деньги-то плачу я. А когда я говорю «ок, вот вам деньги, давайте, решайте мою проблему», то стриминговые сервисы мне говорят «не, у нас-то проблем нет, так что и решать нечего, но ты давай плати».
> Как раз-таки потребители, осознавшие бессмысленность беспокойства, что что-то не хранится у них физически, и позволили стримингам и прочим сервисам по подписке взлететь.

Дело вовсе не в месте хранения, а в наличии/отсутствии полноценного доступа. Могу ли я, например, вырезать отдельный кадр из купленного фильма. Подправить субтитры? Заменить аудидорожку на авторский одноголосый перевод? И т. д.
Одна из проблем со всеми этими стриминговыми сервисами (которой не было у VHS, DVD и т. п) — ты платишь не за контент, а за _возможность потребить контент_.
То есть вы против политики на Хабре, но при этом, нисколько не смущаясь, заявляете, что «новость про матч Испания — Россия является позитивной»? Вы же сами таким вбросом провоцируцете перевод в плоскость политики. Неужели нельзя выражаться более аккуратно?
Вы говорите о разных фотонах: один про фотон-частицу, другой про фотон-квазичастицу. Строго говоря, первых в стекле вообще нет: фотон — это квант свободного эм поля, а в стекле оно сильно взаимодействует с веществом, и квантуется, соответственно, иначе.
12 ...
32

Information

Rating
Does not participate
Registered
Activity