Rust 에러 E0027: pattern does not mention field X (패턴에서 빠진 필드)
E0027은 let Order { item, quantity } = order;처럼 패턴으로 구조체나 열거형 배리언트를 분해하는데, 모든 필드를 언급하지 않았다는 뜻이에요. Rust에서 구조체 패턴은 모든 필드를 처리해야 해요. 이름을 적거나, ..로 “나머지는 됐어”라고 말해야 하죠. 가장 친절한 에러 중 하나예요. rustc가 정확한 해결책을 보여 주는데, 거의 언제나 점 두 개면 돼요. 이 페이지는 Rust 컴파일러 에러 해설의 일부예요.
에러 메시지
섹션 제목: “에러 메시지”error[E0027]: pattern does not mention fields `id`, `paid` --> src/main.rs:10:9 |10 | let Order { item, quantity } = order; // ❌ `id`와 `paid`를 언급하지 않았어요 | ^^^^^^^^^^^^^^^^^^^^^^^^ missing fields `id`, `paid` |help: include the missing fields in the pattern |10 | let Order { item, quantity, id, paid } = order; // ❌ `id`와 `paid`를 언급하지 않았어요 | ++++++++++help: if you don't care about these missing fields, you can explicitly ignore them |10 | let Order { item, quantity, id: _, paid: _ } = order; // ❌ `id`와 `paid`를 언급하지 않았어요 | ++++++++++++++++help: or always ignore missing fields here |10 | let Order { item, quantity, .. } = order; // ❌ `id`와 `paid`를 언급하지 않았어요 | ++++“pattern does not mention fields id, paid“는 “패턴이 id, paid 필드를 언급하지 않았다”는 뜻이에요. 세 개의 help:는 아래에서 하나씩 풀어 볼게요.
이 에러를 내는 프로그램은 다음과 같아요.
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("keyboard"), quantity: 2, paid: true }; let Order { item, quantity } = order; // ❌ `id`와 `paid`를 언급하지 않았어요 println!("{} x {}", quantity, item);}무슨 뜻인가요
섹션 제목: “무슨 뜻인가요”첫 줄에는 패턴이 빠뜨린 필드(id와 paid)가 나와요. ^^^가 패턴 전체에 밑줄을 긋는 건, 문제가 틀린 단어 하나가 아니라 무언가가 빠졌다는 것이기 때문이에요.
그다음 rustc는 help: 제안을 세 개 보여 줘요. 셋 다 맞는 방법이지만 뜻이 서로 달라요.
include the missing fields(빠진 필드를 패턴에 넣어라): 이름을 적어요. 그러면id와paid변수도 생겨요.explicitly ignore them(명시적으로 무시해라):id: _, paid: _라고 써요. 변수는 생기지 않지만, 모든 필드를 이름으로 적은 셈이에요.always ignore missing fields here(여기서는 빠진 필드를 늘 무시해라):..를 써요. “그 밖의 필드는 상관없어”라는 뜻이에요.
입구에 놓인 체크리스트에 “모든 칸에 체크하거나, 기타: 건너뜀에 체크하세요”라고 적혀 있는 것과 같아요. 칸을 그냥 비워 둘 수는 없어요.
Rust가 이렇게 하는 이유
섹션 제목: “Rust가 이렇게 하는 이유”Rust의 구조체 패턴은 따로 말하지 않는 한 완전해야 해요. 그래야 다음에 코드를 읽는 사람에게 의도가 분명히 전달돼요. Order { item, quantity, .. }는 “이 두 개만 필요해”라는 뜻이고, Order { id, item, quantity, paid }는 “모든 필드를 생각해 봤어”라는 뜻이에요. _와 ..로 일부 무시하기를 참고하세요.
진짜 이득은 구조체가 바뀔 때 나타나요. 누군가 Order에 discount 필드를 추가하면, 모든 필드를 이름으로 적은 패턴은 E0027로 깨지고, 새 필드를 처리해야 할지도 모르는 코드를 짚어 줘요. ..가 있는 패턴은 계속 컴파일돼요. 어느 쪽을 원하는지는 내가 고를 수 있지만, Rust가 대신 짐작하지는 않아요.
고치는 방법
섹션 제목: “고치는 방법”방법 1: ..를 붙여서 나머지 무시하기
섹션 제목: “방법 1: ..를 붙여서 나머지 무시하기”대부분은 이 방법을 고르세요. 일부 필드만 필요하다면 패턴 끝에 ..를 붙이세요. let, match, if let, 함수 매개변수에서 모두 쓸 수 있고, 반드시 맨 마지막에 와야 해요.
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("키보드"), quantity: 2, paid: true }; let Order { item, quantity, .. } = order; // ✅ `..`가 `id`와 `paid`를 건너뛰어요 println!("{} x {}", quantity, item);
let orders = [ Order { id: 2, item: String::from("마우스"), quantity: 1, paid: false }, Order { id: 3, item: String::from("모니터"), quantity: 1, paid: true }, ]; for order in &orders { match order { Order { paid: true, item, .. } => println!("{} 배송하기", item), Order { id, .. } => println!("{}번 주문은 결제를 기다리고 있어요", id), } }}실행 결과:
2 x 키보드2번 주문은 결제를 기다리고 있어요모니터 배송하기첫 번째 갈래의 paid: true를 눈여겨보세요. 패턴 안의 필드를 값과 비교할 수도 있고, 그때도 나머지는 ..가 처리해 줘요.
방법 2: 빠진 필드를 적거나, _로 이름을 적고 무시하기
섹션 제목: “방법 2: 빠진 필드를 적거나, _로 이름을 적고 무시하기”그 필드가 실제로 필요할 때, 또는 나중에 필드가 추가되면 패턴이 깨지기를 원할 때 이 방법을 고르세요. 이름 있는 필드를 가진 열거형 배리언트를 match할 때도 같은 에러가 나요.
error[E0027]: pattern does not mention field `y` --> src/main.rs:9:9 |9 | Message::Move { x } => println!("move to x = {}", x), // ❌ `y`를 언급하지 않았어요 | ^^^^^^^^^^^^^^^^^^^ missing field `y`이 에러를 내는 프로그램이에요.
enum Message { Move { x: i32, y: i32 }, Quit,}
fn main() { let m = Message::Move { x: 1, y: 2 }; match m { Message::Move { x } => println!("move to x = {}", x), // ❌ `y`를 언급하지 않았어요 Message::Quit => println!("quit"), }}이동에는 좌표가 두 개 있고, 코드는 사실 둘 다 써야 해요. 그러니 y를 적으세요. 정말로 상관없는 필드라면 y: _가 그 사실을 분명히 말해 주면서도 이름은 적어 둬요.
enum Message { Move { x: i32, y: i32 }, Quit,}
fn main() { let messages = [Message::Move { x: 1, y: 2 }, Message::Move { x: 5, y: 0 }, Message::Quit]; for m in &messages { match m { Message::Move { x, y: 0 } => println!("바닥을 따라 x = {}까지 미끄러지기", x), Message::Move { x, y } => println!("({}, {})(으)로 이동", x, y), // ✅ 두 필드 모두 Message::Quit => println!("종료"), } }
// 모든 필드를 이름으로 적었어요. `Move`에 필드를 추가하면 일부러 여기가 깨져요 if let Message::Move { x, y: _ } = &messages[0] { println!("첫 번째 x = {}", x); }}실행 결과:
(1, 2)(으)로 이동바닥을 따라 x = 5까지 미끄러지기종료첫 번째 x = 1무시하려고 필드 이름을 적는다면 그냥 y가 아니라 y: _라고 쓰세요. 쓰지 않는 y만 적으면 “unused variable”(사용하지 않는 변수) 경고가 나요.
방법 3: 철자가 틀린 필드 이름 고치기
섹션 제목: “방법 3: 철자가 틀린 필드 이름 고치기”E0027이 같은 줄의 E0026과 함께 나올 때 이 방법을 고르세요. 예를 들어 필드가 radius인 배리언트에 Shape::Circle { r }이라고 쓰면 둘 다 나와요. r에 대해서는 E0026(그런 필드가 없음), radius에 대해서는 E0027(언급하지 않음)이에요. rustc의 E0027 help는 r 옆에 radius를 추가하라고 제안하지만, 그건 원하는 게 아니에요. 진짜 해결책은 틀린 이름을 바꾸는 거예요. Shape::Circle { radius }라고 쓰거나, 짧은 변수 이름을 유지하려면 Shape::Circle { radius: r }라고 쓰세요. 그러면 두 에러가 한꺼번에 사라져요. 예제는 E0026 페이지에서 볼 수 있어요.
자주 보게 되는 곳
섹션 제목: “자주 보게 되는 곳”구조체에 필드를 추가한 뒤. Order에 created_at을 추가했더니, 모든 필드를 적은 패턴마다 E0027이 나요. 검사가 제 할 일을 하고 있는 거예요. 패턴마다 정하세요. 이 코드에 created_at이 필요한가요? 필요하면 적고, 아니면 ..를 붙이세요.
함수 매개변수. fn print_order(&Order { item, quantity }: &Order)도 E0027을 내요. 해결: &Order { item, quantity, .. }. let과 함수 매개변수에서의 패턴을 참고하세요.
튜플 구조체와 튜플 배리언트. struct Color(u8, u8, u8);에 대한 Color(r) 패턴도 불완전하지만, rustc는 이걸 E0023, “this pattern has 1 field, but the corresponding tuple struct has 3 fields”(이 패턴에는 필드가 1개인데 대응하는 튜플 구조체에는 3개 있다)로 알려 줘요. 해결 방법은 같은 생각이에요. Color(r, ..)이나 Color(r, _, _)라고 쓰세요.
관련 에러
섹션 제목: “관련 에러”- E0026: struct or variant does not have a field named x: 패턴에 적은 필드 이름이 존재하지 않아요. E0027과 함께 나오는 경우가 많아요.
- E0063: missing field in initializer: 구조체를 만들 때의 같은 생각이에요. 모든 필드에 값이 있어야 해요(또는
..Default::default()). - E0004: non-exhaustive patterns:
match가 모든 배리언트를 다루지 않았어요. E0027은 모든 필드에 관한 에러예요. E0023: this pattern has N fields, but the corresponding tuple struct has M fields: 튜플 구조체 버전이에요(위 참고).- 전체 컴파일러 에러: 에러 페이지 전체 목록이에요.
이해도 점검
섹션 제목: “이해도 점검”이해도 점검
1. struct Point { x: i32, y: i32, z: i32 }가 있어요. 컴파일되면서 x만 꺼내는 패턴은 무엇일까요?
2. Order { item, .. }와 Order { item, id: _, quantity: _, paid: _ }의 차이는 무엇일까요?
3. 같은 줄에서 r에 대해 E0026이, radius에 대해 E0027이 나요. 가장 좋은 해결책은 무엇일까요?
점수: 0 / 3
더 알아보기
섹션 제목: “더 알아보기”- E0027 — Rust error codes index (영어): 이 에러의 공식 설명이에요.
- 패턴 문법 — The Rust Programming Language 한국어판: 구조체 분해하기와
..로 값의 나머지 부분 무시하기를 다뤄요. - Destructuring structs — Rust by Example (영어):
..를 쓴 구조체 패턴을 실행해 볼 수 있는 예제예요. - Patterns — The Rust Reference (영어): 구조체 패턴과 나머지 패턴(rest pattern)의 정확한 규칙이에요.