Я хочу реализовать шаблон объекта значения в D. То есть я хочу иметь изменяемые ссылочные переменные на неизменяемые объекты. T
переменные должны быть назначаемыми, но T
объекты никогда не должны изменять свое состояние.
Меня смущает разница между const
и immutable
в D. Позвольте мне проиллюстрировать мои сомнения скелетом Rational
класса:
class Rational
{
int num;
int den;
Должен ли я объявить num
и den
как const
или immutable
? Есть ли разница для целых чисел?
invariant()
{
assert(den > 0);
assert(gcd(abs(num), den) == 1);
}
Должен ли я объявить invariant
как const
или immutable
? Пометка его как immutable
приводит к ошибке времени компиляции -, но это может быть связано с тем, что другие элементы не помечены immutable
.
this(int numerator, int denominator) {... }
Должен ли я объявить конструктор как const
или immutable
? Что бы это значило?
string toString()
{
return std.string.format("(%s / %s)", num, den);
}
}
Должен ли я объявить toString
как const
или immutable
?
Кажется, вместо того, чтобы отмечать отдельных членов, я могу отметить весь класс:
class Rational
const class Rational
immutable class Rational
Что из этого лучше всего подходит для шаблона объекта значения?
Как насчет pure
? В шаблоне объекта значения методы не должны иметь побочных эффектов, поэтому имеет ли смысл объявлять каждый член как pure
?Пометка toString
как pure
не компилируется, к сожалению, потому что std.string.format
не является чистым; есть ли для этого какая-то особая причина?
Кажется, я также могу объявить сам класс как pure
, но это, похоже, не имеет никакого эффекта, потому что компилятор больше не жалуется на то, что toString
вызывает нечистую функцию.
Что же тогда означает объявить класс как pure
? Его просто игнорируют?