Я узнал, что если переменная явно не объявлена изменяемой с помощью mut
, она становится неизменной (ее нельзя изменить после объявления). Тогда почему у нас есть ключевое слово const
в Rust? Разве они не такие же? Если нет, то чем они отличаются?
В чем разница между неизменяемыми и константными переменными в Rust?
Ответы (6)
const
в Rust - это сокращение от constant и связано с оценкой времени компиляции. Выявляется:
- при объявлении констант:
const FOO: usize = 3;
- при объявлении оцениваемых функций во время компиляции:
const fn foo() -> &'static str
Эти типы значений могут использоваться как общие параметры: [u8; FOO]
. На данный момент это ограничено размером массива, но есть разговоры, планы и надежда на его дальнейшее расширение в будущем.
Напротив, привязка let
относится к вычисляемому значению во время выполнения.
Обратите внимание: несмотря на то, что mut
используется, потому что концепция изменчивости хорошо известна, Rust на самом деле находится здесь. &T
и &mut T
касаются алиасинга, а не изменчивости:
&T
: общая ссылка&mut T
: уникальная ссылка
В частности, некоторые типы обладают внутренней изменчивостью и могут быть изменены с помощью &T
(общие ссылки): Cell
, RefCell
, Mutex
и т. Д.
Примечание: существует альтернативное использование mut
и const
с необработанными указателями (*mut T
и *const T
), которое здесь не обсуждается.
const
не для переменных; это для постоянных значений, которые нигде нельзя хранить; они фактически являются псевдонимом буквального значения.
Не-mut
let
объявляет фактическую переменную, которая создается во время выполнения, может быть перемещена (и больше не доступна) и даже имеет внутреннюю изменчивость (например, если она содержит Cell
членов) в некоторых случаях.
const
не представляет собой ячейку памяти, а представляет собой значение. const
значения встроены непосредственно в месте использования. Любые временные объекты, созданные во время вычисления выражения, доступны только компилятору во время компиляции. Может иметь глобальный масштаб. Не может ссылаться на элементы среды выполнения. Тип должен быть аннотирован.
Пусть значения представляют собой ячейку памяти. Неизменяемость для let
привязки - это принудительная функция компилятора, которую можно изменить с помощью модификатора mut
. Это конструкция времени выполнения. Всегда на месте. Их типы могут быть определены компилятором.
Для полноты, static
также представляет собой ячейку памяти, такую как let, но любые ссылки на одну и ту же статику на самом деле являются ссылкой на одну и ту же ячейку памяти. Статика - это статика. Они скомпилированы в исполняемый файл и доступны в течение всего срока службы запущенной программы. Может иметь глобальный масштаб. Может ссылаться на другую статику. Тип должен быть аннотирован.
Кроме того, мы не можем создавать глобальные элементы с помощью let, но это возможно с помощью const. Вот пример.
const LENGTH:usize = 4;
fn main() {
let arr:[i32; LENGTH] = [10,20,30,40];
for i in 0..LENGTH{
println!("{}", arr[i])
}
}
для получения дополнительной информации об использовании const, static и let: _ 2_ и static
Рассказ немного длиннее.
Константы не могут быть переопределены:
let x = 10u32;
const Y:u32 = 20u32;
let x = 11u32;
//error: duplicate definition of value `Y` [E0428]
//const Y:u32 = 21u32;
println!("x={} Y={}",x,Y); //x=11 Y=20
const
предназначен для констант времени компиляции со всем, что влечет за собой. Например, вы можете создать массив фиксированного размера с размером const
, но вы не можете сделать это с let
привязкой. Конечно, это также означает, что вы можете поместить гораздо больше вещей в let
привязку, чем в const
.