Я думаю, что хитрый момент в этом примере заключается в том, что можно утверждать, что это невозможно.Вы сделали экземпляр Mutable доступным только для чтения, и все же вы можете изменить его значение с помощью функции Mutate (), поэтому в некотором смысле нарушаете концепцию неизменности.Строго говоря, однако, это работает, потому что закрытое поле x не только для чтения.Если вы сделаете одно простое изменение в изменчивом классе, тогда фактически будет применяться неизменность:
private readonly int x;
Тогда функция Mutate () выдаст ошибку компилятора.
Этот пример ясно показывает, как копирование по значению работает в контексте переменных только для чтения.Всякий раз, когда вы вызываете m, вы создаете копию экземпляра, в отличие от копии ссылки на экземпляр - последнее произойдет, если Mutable был классом, а не структурой.
Поскольку каждый раз, когда вы вызываете m, вы вызываете 1) копию экземпляра и 2) копию экземпляра, доступного только для чтения, значение x равно , всегда равным 0 привремя копирования .Когда вы вызываете Mutate () для копии, он увеличивает x на 1, что работает, потому что сам x НЕ доступен только для чтения.Но в следующий раз, когда вы вызываете Mutate (), вы все равно вызываете его с исходным значением по умолчанию, равным 0. Как он говорит в статье, «m является неизменным, а копия - нет».Каждая копия исходного экземпляра будет иметь x как 0, потому что копируемый объект никогда не изменяется, тогда как его копии могут быть изменены.
Может быть, это поможет.