Rust 에러 E0560: struct has no field named X (구조체에 없는 필드 이름)
E0560은 Name { field: value }로 구조체를 만드는데, 적어 넣은 필드 중 하나가 그 구조체에 없다는 뜻이에요. 보통은 오타이거나, 이름이 바뀐 필드이거나, 다른 구조체의 필드예요. rustc가 원래 쓰려던 이름을 정확히 알려 줄 때가 많아서, 가장 빨리 고칠 수 있는 에러 중 하나예요. 이 시리즈의 다른 에러는 Rust 컴파일러 에러 해설에서 볼 수 있어요.
에러 메시지
섹션 제목: “에러 메시지”error[E0560]: struct `User` has no field named `nmae` --> src/main.rs:9:9 |9 | nmae: String::from("Ferris"), // ❌ 오타: 필드 이름은 `name`이에요 | ^^^^ unknown field |help: a field with a similar name exists |9 - nmae: String::from("Ferris"), // ❌ 오타: 필드 이름은 `name`이에요9 + name: String::from("Ferris"), // ❌ 오타: 필드 이름은 `name`이에요 |“struct User has no field named nmae“는 “User 구조체에는 nmae라는 이름의 필드가 없다”는 뜻이에요. 라벨 unknown field는 “알 수 없는 필드”, help는 “비슷한 이름의 필드가 있다”는 뜻이고, 바꿀 줄을 그대로 보여 줘요.
이 에러를 내는 프로그램은 다음과 같아요.
struct User { name: String, email: String, active: bool,}
fn main() { let user = User { nmae: String::from("Ferris"), // ❌ 오타: 필드 이름은 `name`이에요 active: true, }; println!("{}", user.email);}무슨 뜻인가요
섹션 제목: “무슨 뜻인가요”첫 줄은 구조체(User)와 내가 쓴 필드(nmae)를 알려 줘요. ^^^^는 User { ... } 블록 안의 그 필드를 가리켜요. Rust가 그 이름을 struct User의 필드 목록과 비교해 봤는데, 맞는 게 없었던 거예요.
화살표 아래에는 세 가지 힌트 중 하나가 나와요. 각각 알려 주는 게 달라요.
help: a field with a similar name exists(비슷한 이름의 필드가 있다): 오타예요. rustc가 올바른 이름으로 고친 줄을 보여 줘요.note: available fields are: `username`(쓸 수 있는 필드는username): 비슷한 이름이 없어요. 아직 채우지 않은 필드들이 나열돼요.note: all struct fields are already assigned(구조체의 모든 필드에 이미 값을 넣었다): 진짜 필드는 전부 채웠고, 이 필드는 남는 거예요.
rustc가 name이 빠졌다고 따로 불평하지 않는다는 점도 눈여겨보세요. 오타를 고치면 두 문제가 한꺼번에 사라져요.
종이 신청서를 채우면서 전화번호를 “팩스” 칸에 적은 것과 비슷해요. 신청서에 그런 칸이 없으니, 직원이 다시 돌려주는 거죠.
Rust가 이렇게 하는 이유
섹션 제목: “Rust가 이렇게 하는 이유”구조체의 필드는 struct User { ... }를 쓸 때 정해져요. User를 만들 때마다 Rust는 정확히 그 필드들을 넣었는지 검사해요. 빠진 것도, 남는 것도, 철자가 틀린 것도 없어야 해요. 구조체 정의하고 만들기를 참고하세요.
이 검사는 진짜 버그를 잡아 줘요. JavaScript에서 { nmae: "Ferris" }라고 쓰면 아무 말 없이 키가 잘못된 객체가 만들어지고, 한참 뒤 어딘가에서 user.name이 undefined가 돼요. Rust에서는 오타가 컴파일러를 통과할 수 없어서, 프로그램 안의 모든 User에 정말로 name이 있어요.
고치는 방법
섹션 제목: “고치는 방법”방법 1: 철자 고치기
섹션 제목: “방법 1: 철자 고치기”a field with a similar name exists가 보일 때 이 방법을 고르세요. help: 줄의 이름을 쓰면 돼요. 필드 이름은 대소문자를 구별하고, Rust는 snake_case를 쓰니까 userName과 user_name은 서로 다른 이름이에요.
필드 초기화 축약법(field init shorthand)도 조심하세요. User { nmae, email }은 User { nmae: nmae, email: email }이라는 뜻이라서, 변수 이름이 필드 이름과 같아야 해요. 변수 이름을 바꾸거나, 필드를 풀어서 쓰세요. User { name: nmae, email }처럼요.
struct User { name: String, email: String, active: bool,}
fn main() { let user = User { name: String::from("Ferris"), // ✅ 진짜 필드 이름이에요 active: true, }; println!("{} ({}) 활성: {}", user.name, user.email, user.active);
// 축약법: 변수 이름이 필드 이름과 같아요 let name = String::from("Ada"); let other = User { name, email, active: false }; println!("{} ({}) 활성: {}", other.name, other.email, other.active);}실행 결과:
Ferris ([email protected]) 활성: trueAda ([email protected]) 활성: false방법 2: 필드의 새 이름을 쓰거나, 필드 추가하기
섹션 제목: “방법 2: 필드의 새 이름을 쓰거나, 필드 추가하기”“비슷한 이름” 힌트가 없을 때 이 방법을 고르세요. 구조체가 바뀐 경우가 많아요. 누군가 name을 username으로 바꿨거나 필드를 지웠는데, 이 코드는 아직 옛날 이름을 쓰는 거예요. rustc는 남아 있는 필드를 알려 줘요.
error[E0560]: struct `User` has no field named `name` --> src/main.rs:8:9 |8 | name: String::from("Ferris"), | ^^^^ `User` does not have this field | = note: available fields are: `username`라벨 `User` does not have this field는 “User에는 이 필드가 없다”는 뜻이에요.
선택지는 두 가지예요. 구조체가 맞다면, 지금의 필드 이름을 쓰세요. 내 코드가 맞고 구조체에 정말 그 필드가 필요하다면, 구조체 정의에 필드를 추가하세요. 아래에서 Config는 debug에 대해 all struct fields are already assigned를 냈고, 해결책은 구조체에 debug를 추가하는 거였어요.
struct User { username: String, // `name`에서 이름이 바뀌었어요: 새 이름을 써요 email: String,}
struct Config { port: u16, host: String, debug: bool, // 코드에 필요해서 구조체에 추가했어요}
fn main() { let user = User { username: String::from("ferris"), }; println!("{} ({})", user.username, user.email);
let config = Config { port: 8080, host: String::from("localhost"), debug: true, }; println!("{}:{} debug={}", config.host, config.port, config.debug);}실행 결과:
ferris ([email protected])localhost:8080 debug=true방금 업데이트한 크레이트의 구조체라면, 새 버전에서 필드 이름이 바뀌었을 수도 있어요. 그 버전의 구조체를 docs.rs(영어)에서 확인하거나, 크레이트의 변경 기록(changelog)을 보세요. 직접 만든 구조체에 필드를 추가하면, 그 구조체를 만드는 모든 곳에서 그 필드도 채워야 해요. rustc가 그런 곳마다 E0063으로 짚어 줄 거예요(아래 참고).
방법 3: 맞는 구조체 쓰기
섹션 제목: “방법 3: 맞는 구조체 쓰기”내가 쓴 필드가 있긴 한데, 다른 구조체에 있을 때 이 방법을 고르세요. title이 있는 Product와 name이 있는 Customer처럼 비슷한 구조체가 두 개 있으면 헷갈리기 쉬워요.
error[E0560]: struct `Product` has no field named `name` --> src/main.rs:13:9 |13 | name: String::from("Keyboard"), | ^^^^ `Product` does not have this field | = note: available fields are: `title`available fields note를 보세요. 예상하지 못한 필드가 나열돼 있다면, 엉뚱한 구조체를 만들고 있는 거예요. 맞는 구조체 이름을 쓰거나, 원래 쓰려던 구조체의 필드 이름을 쓰세요.
struct Product { title: String, price: u32, // 센트 단위}
struct Customer { name: String, email: String,}
fn main() { let keyboard = Product { title: String::from("Keyboard"), // 상품에는 `title`이 있어요 price: 4900, }; let buyer = Customer { name: String::from("Ana"), // 고객에게는 `name`이 있어요 }; println!("{} 님이 {}를 {}센트에 사요", buyer.name, keyboard.title, keyboard.price); println!("영수증을 보낸 곳: {}", buyer.email);}실행 결과:
Ana 님이 Keyboard를 4900센트에 사요영수증을 보낸 곳: [email protected]방법 4: 튜플 구조체에는 괄호 쓰기
섹션 제목: “방법 4: 튜플 구조체에는 괄호 쓰기”구조체가 struct Point(i32, i32); 같은 튜플 구조체일 때 이 방법을 고르세요. 튜플 구조체의 필드에는 이름이 없어서, Point { x: 1, y: 2 }라고 쓰면 x와 y 둘 다 E0560이 나요. 이때 help: `Point` is a tuple struct, use the appropriate syntax(Point는 튜플 구조체이니 알맞은 문법을 쓰라)와 함께 Point(/* i32 */, /* i32 */)라는 제안이 붙어요. Point(1, 2)처럼 괄호로 만들고, .0과 .1로 읽으세요. 이름을 붙이고 싶다면 정의를 struct Point { x: i32, y: i32 }로 바꾸세요. 튜플과 구조체, 언제 무엇을 쓸까요를 참고하세요.
반대 경우: E0063 missing field
섹션 제목: “반대 경우: E0063 missing field”E0560의 쌍둥이는 E0063이에요. 구조체에 있는 필드인데 내가 채우지 않은 경우예요. Rust는 필드를 대신 채워 주지 않으니, 모든 필드에 값이 있어야 해요.
error[E0063]: missing field `active` in initializer of `User` --> src/main.rs:8:16 |8 | let user = User { | ^^^^ missing `active`“missing field active in initializer of User“는 “User를 초기화하는 곳에 active 필드가 빠졌다”는 뜻이에요. 여러 필드가 빠졌다면 전부 나열해 줘요. missing fields `active`, `email` and `login_count` in initializer of `User`처럼요. 해결: 모든 필드에 값을 주세요. 많은 필드에 적당한 기본값이 있다면, Default를 derive하고 구조체 업데이트 문법 ..으로 나머지를 채우세요.
#[derive(Debug, Default)]struct Settings { volume: u8, dark_mode: bool, language: String,}
fn main() { // 모든 필드를 다 써요 let full = Settings { volume: 80, dark_mode: false, language: String::from("en") };
// 신경 쓰는 필드만 쓰고, 나머지는 Default에서 가져와요 let quick = Settings { dark_mode: true, ..Default::default() };
// 나머지를 다른 값에서 복사해요 let louder = Settings { volume: 100, ..full };
println!("{:?}", quick); println!("{:?}", louder);}실행 결과:
Settings { volume: 0, dark_mode: true, language: "" }Settings { volume: 100, dark_mode: false, language: "en" }숫자의 기본값은 0, bool은 false, String은 빈 문자열이에요. 다른 기본값을 원한다면 impl Default for Settings를 직접 쓰세요. Default: 적당한 시작 값을 참고하세요.
자주 보게 되는 곳
섹션 제목: “자주 보게 되는 곳”.. 업데이트 문법 안에서. Settings { dark: true, ..defaults }도 E0560을 내요. 이때 note는 모든 필드를 나열하고(available fields are: `volume`, `dark_mode`, `language`), 이름이 너무 다르면 “비슷한 이름” 힌트가 없을 수도 있어요. 해결: dark_mode: true.
이름 있는 필드를 가진 열거형 배리언트. enum Shape { Circle { radius: f64 } }에서 Shape::Circle { r: 2.0 }이라고 쓰는 건 같은 실수지만, rustc는 다른 코드를 써요. E0559, variant `Shape::Circle` has no field named `r`(Shape::Circle 배리언트에는 r이라는 필드가 없다)이고, 같은 available fields note와 오타 힌트가 붙어요. 해결: Shape::Circle { radius: 2.0 }. 열거형은 데이터를 담을 수 있어요를 참고하세요.
다른 모듈의 구조체. 필드는 있지만 pub이 아니라면, 대신 E0451, “field balance of struct Account is private”(Account 구조체의 balance 필드는 비공개다)이 나요. 해결: Account::new(...)처럼 모듈이 제공하는 생성자를 쓰세요. 기본은 모두 비공개를 참고하세요.
관련 에러
섹션 제목: “관련 에러”- E0609: no field
xon typeT: 같은 오타인데, 구조체를 만들 때가 아니라 필드를 읽을 때(user.nmae) 난 경우예요. - E0451: field is private in struct literal: 필드는 있지만 여기서는 값을 넣을 수 없어요.
- E0308: mismatched types: 필드 이름은 맞는데 값의 타입이 틀렸어요.
String필드에"Ferris"를 넣은 경우처럼요. E0063: missing field in initializer: 빠뜨린 필드가 있어요(위 참고).E0559: variant has no field named x: 열거형 배리언트에서 나는 E0560이에요.- 전체 컴파일러 에러: 에러 페이지 전체 목록이에요.
이해도 점검
섹션 제목: “이해도 점검”이해도 점검
1. rustc가 note: all struct fields are already assigned라고 해요. 무슨 뜻일까요?
2. let nmae = ...;가 있는데 User { nmae, email }이라고 썼어요. 어떻게 고칠까요?
3. active 없이 User { name, email }처럼 필드를 빠뜨리면 어떤 에러가 날까요?
점수: 0 / 3
더 알아보기
섹션 제목: “더 알아보기”- E0560 — Rust error codes index (영어): 이 에러의 공식 설명이에요.
- 구조체 정의 및 인스턴트화 — The Rust Programming Language 한국어판: 구조체를 만드는 문법, 필드 초기화 축약법, 구조체 업데이트 문법, 튜플 구조체를 다뤄요.
- E0063 — Rust error codes index (영어): 이 에러의 쌍둥이인 “missing field”(필드 누락)의 공식 페이지예요.
- Struct expressions — The Rust Reference (영어):
Name { field: value }, 축약법,..base의 정확한 규칙이에요. Default— 표준 라이브러리 문서 (영어):#[derive(Default)]와..Default::default()가 어떻게 동작하는지 알려 줘요.