구조체

구조체 (Structs)

연관된 값들을 하나의 묶음으로 다루고 싶을 때, 이름 붙인 필드로 타입을 새로 정의하는 게 바로 구조체(struct) 예요. struct 키워드로 선언하는 명목적(nominal) 구조체 타입이죠. Rust의 구조체가 어떻게 생겼고 어떤 종류가 있는지 살펴볼게요.

출처: Rust Reference

본문

문법 (Syntax)

Struct → StructStruct
       | TupleStruct

StructStruct → struct IDENTIFIER GenericParams? WhereClause? ( { StructFields? } | ; )

TupleStruct → struct IDENTIFIER GenericParams? ( TupleFields? ) WhereClause? ;

StructFields → StructField ( , StructField )* ,?

StructField → OuterAttribute* Visibility? IDENTIFIER : Type

TupleFields → TupleField ( , TupleField )* ,?

TupleField → OuterAttribute* Visibility? Type

구조체 선언은 그 구조체가 위치한 모듈이나 블록의 타입 네임스페이스(type namespace) 에 해당 이름을 정의해요. 어디에 선언하느냐에 따라 이름이 들어가는 공간이 정해지는 거죠.

가장 흔한 구조체 아이템과 그 사용 예시를 볼게요.

#![allow(unused)]
fn main() {
struct Point {x: i32, y: i32}
let p = Point {x: 10, y: 11};
let px: i32 = p.x;
}

튜플 구조체 (Tuple structs)

튜플 구조체는 이름 그대로 필드에 이름을 붙이지 않고 튜플처럼 정의하는 명목적 튜플 타입이에요. 타입을 정의하는 것에 더해, 값 네임스페이스(value namespace) 에 같은 이름의 생성자(constructor) 도 함께 정의해요. 그 생성자는 함수라서 호출하면 새로운 인스턴스를 만들 수 있어요.

#![allow(unused)]
fn main() {
struct Point(i32, i32);
let p = Point(10, 11);
let px: i32 = match p { Point(x, _) => x };
}

여기서 Point(10, 11) 이 생성자 호출이고, matchPoint(x, _) 패턴처럼 분해할 때도 같은 이름을 써요.

유닛 구조체 (Unit-like structs)

유닛 구조체는 필드 없이 정의한 구조체예요. 필드 목록 자체를 생략해 버리죠. 이런 구조체는 같은 이름의 타입의 상수(constant) 를 암묵적으로 함께 정의해요. 다음 두 예시는 완전히 같은 의미예요.

#![allow(unused)]
fn main() {
struct Cookie;
let c = [Cookie, Cookie {}, Cookie, Cookie {}];
}

위 코드는 아래와 동일해요.

#![allow(unused)]
fn main() {
struct Cookie {}
const Cookie: Cookie = Cookie {};
let c = [Cookie, Cookie {}, Cookie, Cookie {}];
}

struct Cookie; 한 줄이 타입 정의 + const Cookie: Cookie = Cookie {} 상수 정의를 한 번에 해 주는 셈이에요.

레이아웃 (Layout)

구조체의 정확한 메모리 레이아웃은 지정되어 있지 않아요. 특정 레이아웃을 원한다면 repr 속성으로 지정할 수 있어요.

더 알아보기 (Learn more)