HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Теги: низкоуровневое программирование, указатели, rust</p>
1 <p>Теги: низкоуровневое программирование, указатели, rust</p>
2 <p>Отличительная особенность<strong>Rust</strong>-- возможность его использования в низкоуровневом системном программировании. Речь идет о том, что язык позволяет обращаться к операционной системе напрямую, то есть писать драйверы и даже собственные операционные системы. Но нюанс в том, что при реализации этой возможности используется так называемый<strong>Unsafe</strong>-код, то есть "небезопасный код". А называется он так потому, что при компиляции можно избежать ряда проверок.</p>
2 <p>Отличительная особенность<strong>Rust</strong>-- возможность его использования в низкоуровневом системном программировании. Речь идет о том, что язык позволяет обращаться к операционной системе напрямую, то есть писать драйверы и даже собственные операционные системы. Но нюанс в том, что при реализации этой возможности используется так называемый<strong>Unsafe</strong>-код, то есть "небезопасный код". А называется он так потому, что при компиляции можно избежать ряда проверок.</p>
3 <p>В результате мы получаем палку о двух концах: вроде бы разработчик имеет больше возможностей в плане низкоуровневого программирования, однако вместе с этим снижается и защита от потенциальных ошибок.</p>
3 <p>В результате мы получаем палку о двух концах: вроде бы разработчик имеет больше возможностей в плане низкоуровневого программирования, однако вместе с этим снижается и защита от потенциальных ошибок.</p>
4 <p>Тем не менее,<strong>Unsafe</strong>-контекст имеет право на жизнь. На практике для написания такого кода используется блок кода<strong>unsafe</strong>:</p>
4 <p>Тем не менее,<strong>Unsafe</strong>-контекст имеет право на жизнь. На практике для написания такого кода используется блок кода<strong>unsafe</strong>:</p>
5 <p>Не несмотря на все вышесказанное, в блоке<strong>unsafe</strong>тоже происходит ряд стандартных проверок на владение переменных, использование ссылок и пр. А ключевое слово<strong>unsafe</strong>, по сути, просто предоставляет доступ к 5 возможностям<strong>Rust</strong>и именно эти 5 возможностей не проверяются через компилятор на безопасность памяти. О каких возможностях идет речь:</p>
5 <p>Не несмотря на все вышесказанное, в блоке<strong>unsafe</strong>тоже происходит ряд стандартных проверок на владение переменных, использование ссылок и пр. А ключевое слово<strong>unsafe</strong>, по сути, просто предоставляет доступ к 5 возможностям<strong>Rust</strong>и именно эти 5 возможностей не проверяются через компилятор на безопасность памяти. О каких возможностях идет речь:</p>
6 <ul><li>указатели,</li>
6 <ul><li>указатели,</li>
7 <li>статические переменные,</li>
7 <li>статические переменные,</li>
8 <li>unsafe-функции,</li>
8 <li>unsafe-функции,</li>
9 <li>unsafe-трейты,</li>
9 <li>unsafe-трейты,</li>
10 <li>тип union.</li>
10 <li>тип union.</li>
11 </ul><h2>Указатели</h2>
11 </ul><h2>Указатели</h2>
12 <p>Позволяют выполнять обращение к значениями по конкретным адресам в памяти. Чтобы определить указатели, используется оператор разыменования * (dereference operator).</p>
12 <p>Позволяют выполнять обращение к значениями по конкретным адресам в памяти. Чтобы определить указатели, используется оператор разыменования * (dereference operator).</p>
13 <p>В языке программирования Rust существует 2 вида указателей:</p>
13 <p>В языке программирования Rust существует 2 вида указателей:</p>
14 <ol><li>Неизменяемые либо константные. Определяются в виде<strong>*const T</strong>, где T предоставляет определенный тип.</li>
14 <ol><li>Неизменяемые либо константные. Определяются в виде<strong>*const T</strong>, где T предоставляет определенный тип.</li>
15 <li>Изменяемые. Определяются в виде<strong>*mut T</strong>.</li>
15 <li>Изменяемые. Определяются в виде<strong>*mut T</strong>.</li>
16 </ol><p>Для примера давайте создадим по одному указателю для каждого из вышеупомянутых типов:</p>
16 </ol><p>Для примера давайте создадим по одному указателю для каждого из вышеупомянутых типов:</p>
17 <p>Итак, у нас определены 2 указателя:<strong>n1</strong>и<strong>n2</strong>. Первый из них,<strong>n1</strong>, является константным и указывает на значение типа<strong>i32</strong>. Что касается<strong>n2</strong>, то это изменяемый указатель на значение типа<strong>i32</strong>.</p>
17 <p>Итак, у нас определены 2 указателя:<strong>n1</strong>и<strong>n2</strong>. Первый из них,<strong>n1</strong>, является константным и указывает на значение типа<strong>i32</strong>. Что касается<strong>n2</strong>, то это изменяемый указатель на значение типа<strong>i32</strong>.</p>
18 <p>Чтобы получить указатель на адрес переменной к ссылке на объект, используется операция<strong>as</strong>, преобразующая объект к типу указателя. При этом надо понимать, что для создания изменяемого указателя непосредственно саму переменную следует определять с ключевым словом<strong>mut</strong>:</p>
18 <p>Чтобы получить указатель на адрес переменной к ссылке на объект, используется операция<strong>as</strong>, преобразующая объект к типу указателя. При этом надо понимать, что для создания изменяемого указателя непосредственно саму переменную следует определять с ключевым словом<strong>mut</strong>:</p>
19 <p>Ну а при создании изменяемого указателя используется изменяемая ссылка на эту переменную:</p>
19 <p>Ну а при создании изменяемого указателя используется изменяемая ссылка на эту переменную:</p>
20 <p>Также важно сказать, что сами по себе указатели можно определить и вне блока<strong>unsafe</strong>. Но тут есть нюанс: вне этого блока обратиться к значению в области памяти, на которую указатель указывает,<strong>нельзя</strong>.</p>
20 <p>Также важно сказать, что сами по себе указатели можно определить и вне блока<strong>unsafe</strong>. Но тут есть нюанс: вне этого блока обратиться к значению в области памяти, на которую указатель указывает,<strong>нельзя</strong>.</p>
21 <p>Идем дальше. Как правило, указатели хранят адрес на определенную область в памяти. К примеру, мы можем получить значения указателей, которые определили выше:</p>
21 <p>Идем дальше. Как правило, указатели хранят адрес на определенную область в памяти. К примеру, мы можем получить значения указателей, которые определили выше:</p>
22 <p>Чтобы вывести адрес, хранимый указателем, используется спецификатор<strong>:p</strong>, указывающий, что тут будет выводиться значение указателя.</p>
22 <p>Чтобы вывести адрес, хранимый указателем, используется спецификатор<strong>:p</strong>, указывающий, что тут будет выводиться значение указателя.</p>
23 <p>Осталось посмотреть на консольный вывод:</p>
23 <p>Осталось посмотреть на консольный вывод:</p>
24 <p>Почему оба этих указателя имеют одинаковое значение? Потому, что оба указывают на тот же самый адрес в памяти -- на адрес переменной<strong>num</strong>.</p>
24 <p>Почему оба этих указателя имеют одинаковое значение? Потому, что оба указывают на тот же самый адрес в памяти -- на адрес переменной<strong>num</strong>.</p>
25 <p><em>По материалам https://metanit.com/rust/tutorial/.</em></p>
25 <p><em>По материалам https://metanit.com/rust/tutorial/.</em></p>
26  
26