콘텐츠로 이동

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:33
|
3 | println!("Final score: {}", total_scor);
| ^^^^^^^^^^
|
help: a local variable with a similar name exists
|
3 | println!("Final score: {}", total_score);
| +

“cannot find value total_scor in this scope”는 “이 스코프에서 total_scor라는 값을 찾을 수 없다”는 뜻이에요. help는 “비슷한 이름의 지역 변수가 있다”고 알려 줘요.

이 에러를 내는 프로그램은 다음과 같아요.

fn main() {
let total_score = 42;
println!("Final score: {}", total_scor);
}

^^^^ 표시가 Rust가 찾지 못한 이름을 가리켜요. 3번째 줄의 total_scor예요. “in this scope”(이 스코프에서)는 “이 줄이 있는 자리에서 보기에”라는 뜻이에요. Rust는 그 지점에서 보이는 변수, 함수, 가져온(import) 이름을 전부 확인했지만, 그런 이름은 하나도 없었어요.

help: 줄도 꼭 읽어 보세요. 여기서 rustc는 비슷한 이름의 변수(total_score)를 찾아냈고, 빠진 글자를 +로 보여 주기까지 해요. “a local variable with a similar name exists”(비슷한 이름의 지역 변수가 있음)가 보이면 오타예요.

친구 이름이 “민준”인데 방 건너편에서 “민중아!” 하고 부르는 것과 비슷해요. 친구는 바로 거기 있지만, “민중”이라는 이름에는 아무도 대답하지 않죠.

부르려는 이름이 함수일 때는 같은 에러가 cannot find function ... in this scope(이 스코프에서 함수를 찾을 수 없음)로 나와요.

Rust는 프로그램을 실행하기 전에 모든 이름이 무엇을 가리키는지 정해 둬요. 변수는 let 줄부터, 그 변수를 선언한 블록의 닫는 }까지만 존재해요. 이게 그 변수의 스코프(scope)예요. 그 범위 밖에서는 이름 자체가 없어요.

많은 언어에서는 이런 실수를 그냥 넘어가고, 나중에야 문제를 알게 돼요. JavaScript에서는 오타 하나가 조용히 새 전역 변수를 만들거나 undefined를 줄 수 있어요. Python에서는 실행 중에 NameError가 나는데, 하필 테스트가 한 번도 지나가지 않은 코드 경로에서만 날 수도 있어요. Rust는 컴파일할 때 매번 잡아 줘요.

함수도 모듈과 함께 같은 원리를 따라요. mod billing 안에 있는 함수는 경로를 써 주거나 use로 가져오기 전까지 main에서 보이지 않아요.

help: 줄이 비슷한 이름이 있다고 말할 때 이 방법을 고르세요. 단연 가장 흔한 원인이에요. Rust의 이름은 대소문자도 구분해서, Total_score와 total_score는 서로 다른 이름이에요.

fn main() {
let total_score = 42;
println!("Final score: {}", total_score);
}

실행 결과:

Final score: 42
▶ 직접 실행해 보기

방법 2: 두 곳에서 모두 보이는 자리에 변수 선언하기

섹션 제목: “방법 2: 두 곳에서 모두 보이는 자리에 변수 선언하기”

help가 “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);
}

실행 결과:

132
330
88
세금 포함 마지막 가격: 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;
|

help는 “이 함수를 가져와 보라”며 넣을 use 줄을 보여 줘요. 전체 경로로 호출하거나(billing::total_with_tax(50.0)), rustc가 제안한 use 줄을 추가하면 돼요.

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도 붙어 있어야 해요. pub이 없으면 다른 에러(E0603, “function is private”)가 나요. 경로와 use가 어떻게 동작하는지는 모듈을 참고하세요.

메서드 안에서 찾지 못한 이름이 구조체의 필드일 때 이 방법을 고르세요. 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` parameter
    7 | self.count = 0;
    | ^^^^ `self` value is a keyword only available in methods with a `self` parameter

    “이 함수에는 self 매개변수가 없고, self는 self 매개변수가 있는 메서드에서만 쓸 수 있다”는 뜻이에요. 해결: self 매개변수를 추가하세요. rustc는 &self를 제안하지만, 이 함수는 필드를 바꾸니까 fn reset(&mut self)가 필요해요.

이해도 점검

1. rustc가 "help: a local variable with a similar name exists"라고 말해요. 가장 그럴듯한 원인은 무엇일까요?

2. for 반복문 안에서 let found = true;를 쓰고, 반복문이 끝난 뒤에 found를 썼어요. 왜 에러가 날까요?

3. send 함수가 mod mailer 안에 있어요. main에서 send()로 부를 수 있게 해 주는 줄은 무엇일까요?

점수: 0 / 3