Skip to content

Latest commit

 

History

History
84 lines (62 loc) · 2.53 KB

mutrefimmut.md

File metadata and controls

84 lines (62 loc) · 2.53 KB

Изменяемые и нет ссылки на изменяемые и нет данные

Изменяемый указатель на неизменяемые данные:

C++

char const * a;

D

const(char)* a;
immutable(char)* a;

В обоих случаях мы можем изменять значение самого указателя (менять адрес, который он хранит), но не можем менять данные по этому адресу.

Неизменяемый указатель на неизменяемые данные

Тут код будет проще на D:

C++

char const * const a;

D

const(char*) a;
immutable(char*) a;

Здесь мы уже не можем изменить ни указатель не данные по адресу.

Неизменяемый указатель на изменяемые данные

Вот тут возникает проблема с D: средствами языка это не реализуется. Но можно сделать это через принудительный обход системы типов. Такой подход категорически не рекомендуется и, возможно, создаёт ситуации для udefined behavior. В большинстве случаев, когда нужно быть уверенным, что поле нельзя будет перезаписать другим объектом, но объект нужно менять можно использовать приватные поля/переменные, возвращаемые методами/функциями.

C++

char * const a;

D (проверенно на linux dmd-2.078.0)

import std.stdio;

const struct Imm(T)
{
    private T _data; // const транзитивно распостраняется на поля
    alias data this;
    // Реализация обхода системы типов через приведение указателей
    ref T data() const { return *(cast(T*)&_data); }
}

void main()
{
    auto a = Imm!(char[])(new char[](10));
    // typeof(a) == const Imm!(char[])
    //a = "hello"; // присвоить нельзя
    a[] = "helloworld"; // заполнить значениями можно
    writeln(a);
    auto b = Imm!(char[])(new char[](2));
    b[0..2] = "ab";
    b.length = 10;
    b[2..5] = "cde";
    writeln(b);

    //a = b; // нельзя
}