Я часто видел термины immutable
и const
использовал их взаимозаменяемо. Однако, из моего (небольшого) опыта, они сильно отличаются по «контракту», который они заключают в коде:
Immutable заключает договор о том, что этот объект не изменится (например, кортежи Python, строки Java).
Const заключает договор о том, что в области действия этой переменной она не будет изменена (никаких обещаний относительно того, что другие потоки могут сделать с объектом, на который указывает этот период, например, с ключевым словом C / C ++).
Очевидно, что они не эквивалентны, если только язык не является однопоточным (PHP) или не имеет линейной или уникальной системы ввода (Clean, Mercury, ATS).
Во-первых, верно ли мое понимание этих двух понятий?
Во-вторых, если есть разница, почему они почти исключительно используются взаимозаменяемо?
источник
const
не существует в каждом языке, а изменчивость и неизменность не существуют в каждом языке, поэтому использование этого языка в качестве агониста не применимо. Это язык конкретных только там , где применяются эти понятия.Ответы:
Я поговорю с C ++, где эта разница наиболее актуальна.
Как вы правильно заметили, неизменность означает, что объект не может измениться вообще после его создания. Это создание может, конечно, происходить во время выполнения, т. Е.
const
Объект не обязательно является константой времени компиляции. В C ++ объект является неизменным, если встречаются (1) и (2) или (3):У него нет членов, объявленных
mutable
мутированнымиconst
функциямиОбъявлено
const
const
функции-члены не используютconst_cast
для удаленияconst
квалификации, чтобы изменить членовОднако вы могли бы также рассмотреть модификаторы доступа: если операция внутренне мутирует экземпляр, но не влияет на состояние экземпляра, наблюдаемого через его открытый интерфейс, то объект «логически неизменен».
Таким образом, C ++ предоставляет инструменты, необходимые для создания неизменяемых объектов, но, как и большинство всего в C ++, инструменты минимально достаточны и требуют реального усердия для реального использования. Состояние экземпляра не обязательно ограничено переменными-членами экземпляра - поскольку C ++ не обеспечивает способ обеспечения ссылочной прозрачности, он может также включать глобальное состояние или состояние класса.
const
также имеет другую функцию в C ++: квалифицировать ссылки и указатели.const
Ссылка может относиться к не-const
объекта. Разрешается (хотя и не всегда необходимо или целесообразно) использоватьconst_cast
для изменения объекта посредствомconst
ссылки, если и только если этот объект объявлен как неconst
:И, конечно, это неопределенное поведение, чтобы изменить
const
объект:источник
Говоря о Java, где ключевое слово «final» представляет «const», рассмотрим:
Это означает, что
someone
НИКОГДА не может ссылаться на другой объект Person. Но вы все равно можете изменить данные о человеке, которого направляют. Напримерsomeone.setMonthlySalary(10000);
Но, если бы это
someone
был «неизменяемый» объект, было бы верно одно из следующих действий: (a) у вас не было бы метода с именемsetMonthlySalary
(b) вызов setMonthlySalary всегда вызывал бы исключение, такое какUnsupportedOperationException
источник
Неизменяемыми объектами являются те, которые не изменяют состояние после его создания. Например;
В этом примере объект myComplexStr является неизменным, но не постоянным, поскольку его значение вычисляется. И он неизменен, потому что это строка, имеет свойство статической длины и не может изменяться.
Const-объекты обычно используются для идентификации некоторых реальных констант, значения которых известны до компиляции, таких как Pi, "USA", "StackOverflow.com", номера портов и так далее.
С этой точки зрения Const отличается от неизменяемых объектов, потому что их значения не рассчитываются программой.
Но если вы говорите о ключевом слове «const» в C ++, вы можете сказать, что «const» используется для создания неизменяемых объектов.
источник
const
подобного поведения - неопределенное поведение, независимо от того, где оно размещено, IIRC. А неопределенное поведение хуже любой конкретной ошибки, которая гарантированно произойдет. Это означает, что вы больше не используете C ++ - C ++ не предоставляет средств для измененияconst
значения (за исключениемmutable
членов, конечно, но это не ваша точка зрения), поэтому, что касается C ++, вы не можете это сделать. Какие конкретные реализации позволяют разрешить - это совсем другой вопрос (и, держу пари, если вы компилируете с оптимизацией, трюк, который вы потянули, не повлияет на последующие выражения,pi
потому что он был заменен).Да, но ваш второй вопрос показывает, что вы не понимаете этих различий.
const
в C ++ используется только для уровня доступа (это означает «только для чтения») , а не для неизменности. Это означает, что сам доступ полностью отделен от данных. Например, вы можете манипулировать некоторыми данными, а затем предоставлять их через константную ссылку. Доступ только для чтения, но сами данные, как и все данные, являются изменчивыми.Только ограничения гарантированного доступа, в то время как неизменяемость (как, например, в D) не подразумевает никакого способа изменить данные на любой стадии жизни объекта .
Теперь вы можете смоделировать неизменность в C ++, убедившись, что к некоторым данным нельзя получить доступ каким-либо иным способом, кроме const, и убедитесь, что они инициализированы, а затем не затрагиваются. Но это не является надежной гарантией, поскольку такие языки, как D, дают вам, когда вы помечаете свои данные как неизменные. Язык гарантирует, что вообще невозможно выполнять какие-либо операции, модифицирующие эти данные, в то время как в C ++ вы все еще потенциально можете изменять данные с помощью константного преобразования и изменчивости, если это действительно необходимо.
В конце концов, это совсем не то же самое, что и вовсе не дает одинаковых гарантий.
источник
Говоря о JavaScript, ключевые слова
const
иObject.freeze
const
относится к привязкамvariables
. Это создает неизменную привязку, вы не можете присвоить ей новое значение.Object.freeze
работает над значениями объекта. Это делает объект неизменным . А именно, вы не можете изменить его свойства.источник
В C ++ они одинаковы. Хотя вы можете изменить
const
объект, если у вас есть его расположение в памяти и разрешение ОС для записи в эту память.источник
В C, C ++ и связанных языках также существует разница между объектом const и вашей ссылкой или указателем на объект, являющийся константной ссылкой.
Если вы попытаетесь изменить постоянный объект, вы получите неопределенное поведение. (Вы можете попытаться изменить константный объект, например, взяв его адрес, приведя адрес к неконстантному указателю, а затем используя этот неконстантный указатель для изменения объекта).
Указатель константы или ссылка с другой стороны просто говорит компилятору, что вы не можете использовать этот указатель или ссылку для изменения объекта. Вы можете привести указатель или ссылку и попытаться изменить объект. Если сам объект был постоянным, произойдут плохие вещи. Если объект на самом деле не был постоянным, он изменится. Это, конечно, может запутать пользователей вашего кода и вполне может привести к ошибкам.
В C, если вы используете строковый литерал, такой как «Hello», пять символов и завершающие нулевые байты фактически постоянны, но вы получаете неконстантный указатель. Очень плохая идея использовать этот неконстантный указатель для изменения объекта.
В C вы можете иметь указатель «const restrict». Это означает, что объект, на который указывает объект, является временно постоянным. Если объект изменяется любым способом, пока указатель «const restrict» находится в области видимости, вы получите неопределенное поведение. Это сильнее, чем указатель const, который только мешает вам изменить объект через этот указатель.
источник