Ошибка Rust E0425: cannot find value in this scope (значение не найдено)
Ошибка E0425 значит, что Rust искал имя в одном конкретном месте твоего кода и не нашёл его там. Это одна из самых частых ошибок вообще, и почти всегда она исправляется быстро: обычно это опечатка, переменная, которая живёт в другом блоке, или функция, которой нужен путь к модулю. Эта страница — часть раздела Ошибки компилятора Rust с объяснениями.
Сообщение об ошибке
Заголовок раздела «Сообщение об ошибке»error[E0425]: cannot find value `total_scor` in this scope --> src/main.rs:3:35 |3 | println!("Итоговый счёт: {}", total_scor); | ^^^^^^^^^^ |help: a local variable with a similar name exists |3 | println!("Итоговый счёт: {}", total_score); | +Компилятор пишет: не удаётся найти значение total_scor в этой области видимости. Подсказка help добавляет: есть локальная переменная с похожим именем.
Вот программа, которая выдала эту ошибку:
fn main() { let total_score = 42; println!("Итоговый счёт: {}", total_scor);}Что это значит
Заголовок раздела «Что это значит»Значки ^^^^ отмечают имя, которое Rust не смог найти: total_scor в строке 3. «In this scope» («в этой области видимости») значит «с того места, где стоит эта строка». Rust проверил все переменные, функции и импорты, видимые в этой точке, и ни у чего не было такого имени.
Прочитай и строку help:. Здесь rustc заметил переменную с похожим именем (total_score) и даже показал недостающую букву значком +. Если видишь «a local variable with a similar name exists», это опечатка.
Это как крикнуть через всю комнату «Алесандр!», когда друга зовут Александр. Он стоит рядом, но на «Алесандра» никто не отзывается.
Та же ошибка бывает и в виде cannot find function ... in this scope («не удаётся найти функцию»), когда недостающее имя — функция, которую ты вызываешь.
Почему Rust так делает
Заголовок раздела «Почему Rust так делает»Rust ещё до запуска программы решает, на что указывает каждое имя. Переменная существует только от своей строки с let до закрывающей } блока, в котором объявлена. Это её область видимости. За пределами этой области имени просто нет.
Многие языки позволили бы такому проскочить, и ты узнал бы о проблеме позже. В JavaScript опечатка может тихо создать новую глобальную переменную или дать undefined. В Python ты получил бы NameError во время выполнения — возможно, только в той ветке кода, до которой твои тесты не добрались. Rust ловит это при компиляции, каждый раз.
С функциями работает та же идея, только через модули: функция внутри mod billing не видна из main, пока ты не укажешь её путь или не подключишь её через use.
Как исправить
Заголовок раздела «Как исправить»Исправление 1: исправь написание
Заголовок раздела «Исправление 1: исправь написание»Выбирай этот вариант, когда строка help: говорит, что существует похожее имя. Это самая частая причина. Имена в Rust ещё и чувствительны к регистру, так что Total_score и total_score — разные имена.
fn main() { let total_score = 42; println!("Итоговый счёт: {}", total_score);}Вывод:
Итоговый счёт: 42Исправление 2: объяви переменную там, где её видят оба места
Заголовок раздела «Исправление 2: объяви переменную там, где её видят оба места»Выбирай этот вариант, когда подсказка говорит «the binding is available in a different scope in the same function» («привязка доступна в другой области видимости той же функции»). Ты создал переменную внутри цикла или блока if, а потом использовал её после }. Сломанная версия выглядит так:
fn main() { let prices = [120, 300, 80]; for price in prices { let with_tax = price + price / 10; println!("{with_tax}"); } println!("Последняя цена с налогом: {}", with_tax); // error[E0425]}with_tax создаётся заново на каждом проходе цикла и выбрасывается на } цикла. Если значение нужно после цикла, объяви переменную до цикла и обновляй её внутри:
fn main() { let prices = [120, 300, 80]; let mut last_with_tax = 0;
for price in prices { let with_tax = price + price / 10; println!("{with_tax}"); last_with_tax = with_tax; }
println!("Последняя цена с налогом: {}", last_with_tax);}Вывод:
13233088Последняя цена с налогом: 88То же исправление работает, если ты использовал переменную до её строки с let. Rust читает сверху вниз, так что просто подними let выше.
Исправление 3: укажи путь к функции или добавь use
Заголовок раздела «Исправление 3: укажи путь к функции или добавь use»Выбирай этот вариант для cannot find function, когда функция живёт в другом модуле. Rust выводит:
error[E0425]: cannot find function `total_with_tax` in this scope --> src/main.rs:8:17 |8 | let total = total_with_tax(50.0); | ^^^^^^^^^^^^^^ not found in this scope |help: consider importing this function |1 + use crate::billing::total_with_tax; |Подсказка предлагает импортировать функцию. Либо вызывай её с полным путём (billing::total_with_tax(50.0)), либо добавь строку use, которую предлагает rustc:
mod billing { pub fn total_with_tax(amount: f64) -> f64 { amount * 1.2 }}
use crate::billing::total_with_tax;
fn main() { let total = total_with_tax(50.0); println!("{total}");}Вывод:
60Функция к тому же должна быть pub. Без этого ты получишь другую ошибку (E0603, «function is private» — «функция приватная»). Как работают пути и use, рассказано в уроке Модули.
Исправление 4: добавь self. перед полем
Заголовок раздела «Исправление 4: добавь self. перед полем»Выбирай этот вариант внутри метода, когда недостающее имя — одно из полей твоей структуры. Если ты пришёл из Java или C#, естественно написать count и ожидать, что это поле. В Rust всегда пишут self.count. rustc подсказывает: help: you might have meant to use the available field («возможно, ты хотел использовать доступное поле»).
struct Counter { count: u32,}
impl Counter { fn report(&self) { println!("Счётчик: {}", self.count); }}
fn main() { let c = Counter { count: 3 }; c.report();}Вывод:
Счётчик: 3Где это обычно встречается
Заголовок раздела «Где это обычно встречается»-
Переменная задана внутри
if.if balance > 50 { let bonus = 10; }, а потомprintln!("{}", bonus)— ошибка, потому чтоbonusумерла на}. Исправление: пустьifсам выдаёт значение:let bonus = if balance > 50 { 10 } else { 0 };. -
Конструктор вызывают без типа.
let p = new("ferris");даётcannot find function `new` in this scope. Исправление:newпринадлежит типу, так что пишиPlayer::new("ferris"). -
selfв функции без параметраself. Это близкий родственник E0425 — E0424:error[E0424]: expected value, found module `self`--> src/main.rs:7:9|6 | fn reset() {| ----- this function doesn't have a `self` parameter7 | self.count = 0;| ^^^^ `self` value is a keyword only available in methods with a `self` parameterКомпилятор объясняет: у этой функции нет параметра
self, аselfдоступен только в методах с таким параметром. Исправление: добавь параметрself. rustc предлагает&self, но эта функция меняет поле, так что нужноfn reset(&mut self).
Связанные ошибки
Заголовок раздела «Связанные ошибки»- E0599: no method found: имени, которое ты вызываешь как метод, у этого типа нет.
- E0382: use of moved value: переменная существует, но её значение перемещено.
- E0308: mismatched types: имя нашлось, но у него не тот тип.
- E0277: trait bound not satisfied: типу не хватает трейта, который нужен какому-то коду.
- Все ошибки компилятора: полный список с кратким описанием каждой.
Проверь себя
Заголовок раздела «Проверь себя»Проверь себя
1. rustc пишет "help: a local variable with a similar name exists". Какая причина вероятнее всего?
2. Ты пишешь let found = true; внутри цикла for и используешь found после цикла. Почему это не работает?
3. Функция send живёт в mod mailer. Какая строка позволит main вызывать её как send()?
Результат: 0 / 3
Что почитать
Заголовок раздела «Что почитать»- E0425 — Rust error codes index (на английском): официальное объяснение с дополнительными примерами.
- Введение путей в область видимости с помощью ключевого слова use — книга «Язык программирования Rust» (перевод на русский): как
useделает видимыми функции из других модулей. - Область видимости и затенение — Rust на примерах (перевод на русский): короткие примеры того, где переменная живёт и где умирает.
- Синтаксис метода — книга «Язык программирования Rust» (перевод на русский): почему методы используют
selfи как через него добраться до полей. - E0424 — Rust error codes index (на английском): родственная ошибка —
selfвне метода.