Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- animation
- pushnamed
- 코틀린
- text
- 파이썬
- set
- crawler
- import
- Collection
- Android
- python
- List
- variable
- kotlin
- 함수
- Flutter
- 다트
- 클래스
- DART
- 웹크롤러
- 플러터
- 콜렉션
- 크롤러
- textstyle
- package
- Class
- map
- rust
- ML
- function
Archives
- Today
- Total
조용한 담장
Rust Using Structs to Structure Related Data - Quick Reference 본문
5. Using Structs to Structure Related Data
이 글은 Rust 공식 문서 5장(Using Structs to Structure Related Data)의 내용을 기반으로 빠르게 훑어볼 수 있도록 정리한 요약본입니다.
5.1. Defining and Instantiating Structs
https://doc.rust-lang.org/book/ch05-01-defining-structs.html
핵심 개념 및 코드 스니핏
- 정의 (Definition):
struct키워드로 필드와 타입을 묶음.
struct User {
username: String,
email: String,
active: bool,
}
- 인스턴스화 (Instantiation): 정의된 키에 값을 할당 (순서 무관).
let user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
};
- 가변성 (Mutability): 인스턴스 전체가
mut여야 필드 변경 가능.
let mut user1 = User { /* ... */ };
user1.email = String::from("another@example.com"); // 가능
// let user2 = User { ... }; user2.email = ...; // 불가능 (컴파일 에러)
- 필드 초기화 축약 (Field Init Shorthand): 변수명과 필드명이 같으면 생략.
fn build(email: String, username: String) -> User {
User {
email, // email: email 과 동일
username, // username: username 과 동일
active: true,
}
}
- 구조체 갱신 문법 (Struct Update Syntax):
..instance로 나머지 필드 복사.
// user1의 active 등을 가져오고 email만 새로 설정
let user2 = User {
email: String::from("new@example.com"),
..user1
};
// 주의: String 같은 힙 데이터 필드가 user1에서 user2로 이동(Move)되면 user1은 재사용 불가
- 튜플 구조체 (Tuple Structs): 필드명 없는 구조체.
struct Color(i32, i32, i32);
let black = Color(0, 0, 0);
// black.0 으로 접근
- 유닛 구조체 (Unit-Like Structs): 필드가 없는 구조체 (트레이트 구현용).
struct AlwaysEqual;
let subject = AlwaysEqual;
통합 실전 예제
struct User {
active: bool,
username: String,
email: String,
}
struct Color(i32, i32, i32); // 튜플 구조체
struct AlwaysEqual; // 유닛 구조체
fn main() {
// 1. 가변 인스턴스 생성
let mut user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
};
// 2. 필드 값 변경
user1.email = String::from("another@example.com");
// 3. 구조체 갱신 문법 (Struct Update Syntax)
// user1의 username(String) 소유권이 user2로 이동(Move)됨에 주의!
let user2 = User {
email: String::from("user2@example.com"),
..user1
};
println!("User2 Email: {}", user2.email);
println!("User2 Username: {}", user2.username);
// println!("{}", user1.username); // 컴파일 에러! (소유권 이동됨)
println!("User1 Active: {}", user1.active); // Copy 타입(bool)은 여전히 사용 가능
// 4. 튜플 구조체 사용
let black = Color(0, 0, 0);
println!("Black Color R: {}, G: {}, B: {}", black.0, black.1, black.2);
// 5. 유닛 구조체 사용
let _subject = AlwaysEqual;
}
5.1 Defining and Instantiating Structs - 테스트 코드(Rust Playground)
Gist
5.2. An Example Program Using Structs
https://doc.rust-lang.org/book/ch05-02-example-structs.html
핵심 개념 및 코드 스니핏
- 의미 부여 (Semantic Grouping): 개별 변수보다 구조체가 데이터의 관계를 명확히 함.
// Bad: fn area(width: u32, height: u32) -> u32
// Good:
struct Rectangle { width: u32, height: u32 }
fn area(rect: &Rectangle) -> u32 { ... }
Debug트레이트 파생 (Derive Debug): 구조체 출력을 위해#[derive(Debug)]추가.
#[derive(Debug)]
struct Rectangle { width: u32, height: u32 }
- 포맷팅 출력:
{:?}또는{:#?}사용.
let rect = Rectangle { width: 30, height: 50 };
println!("rect: {:?}", rect); // 한 줄 출력
println!("rect: {:#?}", rect); // 들여쓰기 출력 (Pretty Print)
dbg!매크로: 디버깅 정보를 stderr로 출력하고 값을 반환.
let width = dbg!(30 * 2); // 60을 출력하고 변수에 할당
dbg!(&rect); // 파일명, 라인번호, 값 출력
통합 실전 예제
#[derive(Debug)] // 구조체를 출력 가능하게 만듦
struct Rectangle {
width: u32,
height: u32,
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
fn main() {
let scale = 2;
let rect1 = Rectangle {
// dbg!는 값을 반환하므로 필드 할당 식 중간에 사용 가능
width: dbg!(30 * scale),
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
area(&rect1)
);
// {:?} : 기본적인 Debug 출력
println!("rect1 is {:?}", rect1);
// {:#?} : 읽기 편한 Debug 출력
println!("rect1 is {:#?}", rect1);
// dbg! 매크로 활용 (소유권을 뺏기지 않으려 참조를 넘김)
dbg!(&rect1);
}
5.2 An Example Program Using Structs - 테스트 코드(Rust Playground)
Gist
5.3. Methods
https://doc.rust-lang.org/book/ch05-03-method-syntax.html
핵심 개념 및 코드 스니핏
- 메서드 정의 (
implblock): 함수가 아닌 구조체 컨텍스트 내의 메서드.
impl Rectangle {
fn area(&self) -> u32 { /* ... */ }
}
self파라미터의 종류:
&self: 읽기 전용 (가장 많이 사용).&mut self: 인스턴스 내부 값 변경 시 사용.self: 소유권을 가져감 (메서드 종료 시 인스턴스 해제됨).
impl Rectangle {
fn read(&self) {} // 읽기
fn change(&mut self) {} // 쓰기
fn consume(self) {} // 소유권 가져오기
}
- 연관 함수 (Associated Functions):
self가 없는 함수. 주로 생성자(::new)로 사용.
impl Rectangle {
fn square(size: u32) -> Self { // Self는 Rectangle의 별칭
Self { width: size, height: size }
}
}
// 호출: Rectangle::square(10);
- 다중
impl블록: 코드를 분리하여 작성 가능.
impl Rectangle { fn area(&self) ... }
impl Rectangle { fn can_hold(&self) ... }
통합 실전 예제
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// 1. 메서드: &self (Immutable Borrow)
fn area(&self) -> u32 {
self.width * self.height
}
// 2. 메서드: 다른 인스턴스와 상호작용
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
// 3. 메서드: 필드명과 동일한 이름 (Getter)
fn width(&self) -> bool {
self.width > 0
}
// 4. 메서드: &mut self (Mutable Borrow) - 상태 변경
fn resize(&mut self, factor: u32) {
self.width *= factor;
self.height *= factor;
}
}
// 별도의 impl 블록 (조직화를 위해 분리 가능)
impl Rectangle {
// 5. 연관 함수: self가 없음 (생성자 역할)
// 호출 시 :: 연산자 사용
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
fn main() {
let mut rect1 = Rectangle { width: 30, height: 50 };
let rect2 = Rectangle { width: 10, height: 40 };
let rect3 = Rectangle { width: 60, height: 45 };
// 연관 함수 호출 (::)
let sq = Rectangle::square(20);
println!("Area of rect1: {}", rect1.area()); // 자동 참조/역참조 기능으로 (&rect1).area()와 동일
// 메서드와 필드 이름이 같을 경우, 괄호() 유무로 구분
if rect1.width() {
println!("Rect1 width exists: {}", rect1.width);
}
println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
// 상태 변경 메서드 호출
rect1.resize(2);
println!("Resized rect1: {:#?}", rect1);
println!("Square constructed: {:?}", sq);
}
'Rust' 카테고리의 다른 글
| Rust Understanding Ownership - Quick Reference (0) | 2025.12.29 |
|---|---|
| Rust Common Programming Concepts - Quick Reference (0) | 2025.12.22 |
Comments