Comments 13
Обычно, интерфейс класса — это набор «соглашений» о том, какие данные и как будут переданы, какой функционал существует.
Для безопасности в смысле БЕЗОПАСНОСТИ никогда не следует шарить данные для недоверенных потребителей или надеяться на const. Нужно использовать средства операционных систем для общения с недоверенными модулями или системами, используя каналы/шаренную память/read-only страницы памяти и все остальные крутые штуки, которые предоставляются ядром и интерфейсом операционных систем, либо специальными средствами защиты, такие как SELinux/AppArmor/etc
Это для совсем уже «чужих». В рамках одной кодовой базы остается только const.
в erlang данные под капотом на самом деле не копируются без надобности (copy on write), даже если вы изменяете только часть данных — то только они и изменятся на остальные будут ссылки. Поэтому расход памяти не особо и большой получается.
Вопрос преимуществ/недостатков константности на самом деле весьма непрост. После того, как я столкнулся с невозможностью использовать const correctness в языке D, как я это делал в C++, мне пришлось пройти через путь «отрицание/гнев/принятие» и пересмотреть свои взгляды на эту тему. Есть весьма интересная статья «Why const sucks», написанная одним из котрибьюторов языка D. Его размышления заставляют задуматься, а действительно ли так необходима логическая константность в C++, как я думал раньше?
А я так и не понимаю, зачем защищать от разработчика? ИМХО, наилучший вариант это питоновский, в нем:
— все написано явно и честно;
— в сумме порождает наименьшее количество геморроя.
Вопрос привычки, полагаю. Мне после С++ постоянно не хватает чего-то в других языках. Кому-то после Python в С++ будет казаться, что язык предлагает/требует слишком много.
Можно пойти ещё немножко дальше и вместо эрланга рассмотреть хаскель. Там и поменять не получится, и при передаче значения в функцию ничего не копируется.

Было бы интересно в сравнение добавить Rust, там всё по умолчанию immutable, а для того чтобы сделать что-то не const (в смысле плюсов) надо прописовать ключевое слово mut.
На счёт средств обхода этого ограничения не знаю, но наверняка можно внутри unsafe блока.

Эх, несколько лет назад я выбирал как раз между Go и Rust, но выбрал Go. Так что с Rust я не знаком. Но мне тоже было бы интересно :)
Чем еще опасен такой хак в Java: строки в здесь могут храниться в пуле, и на одно и то же значение в пуле могут указывать никак не связанные друг с другом, просто одинаковые строки. Изменил одну — изменил их все.

Вы не изменяли строку, вы изменили ссылку на экземпляр строки.
До вызова evilConsumer() поле strValue содержало ссылку на экземпляр класса String со значением "Fish", а после — на другой экземпляр, хранящий значение "James Bond".
Рыба при этом не пострадала и всё так же оставалась рыбой.


Для того, чтобы превратить рыбу в Джеймса Бонда вам пришлось бы залезть через reflection в экземпляр строки. Делать так, естественно, не нужно.

Неудачно получилось. Я изменил строку (код), но убрал этот пример из текста, чтобы не перегружать статью.
Спасибо за замечание. Подумаю, как переписать текст, чтобы стало понятнее.
Во-вторых, я вдруг сформулировал для себя мысль, что очень грубо языки программирования можно разделить на те, которые пытаются на уровне синтаксиса и семантики ограничить доступ к тем или иным данным, и на те, которые даже не пытаются, перекладывая эти заботы на пользователей.

Я, после прочтения статьи, выделил для себя две категории:
языки которые не позволяют случайно изменить «внутренние» данные (а например только через рефлексию) и остальные яп. :)

Статья клёвая, спасибо!
А сколько, если не секрет, времени заняло написание всех foo'хов?

Cпасибо!

Код примеров я неспеша писал вечерами недели две, наверное. Это с учетом двукратного переписывания :)
Only those users with full accounts are able to leave comments. Log in, please.