[Rust]

[Rust] 데이터 구조체

극꼼 2023. 7. 29. 22:12
반응형


<구조체>

다른 타입의 여러 값을 가질 수 있다는 점에서 튜플과 비슷하지만, 각각을 필드에 정의하고 명명할 수 있다는 점에서 차이가 있습니다.

struct를 사용해 다음과 같이 정의하여 사용할 수 있습니다.

인스턴스인 my_data를 생성할 때 값을 입력하는 순서는 중요하지 않지만, 모든 필드에 값을 입력해주어야 합니다.

struct UserData {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

let my_data = UserData {
    username : String::from("Geukggom"),
    email : String::from("geukggom@gmail.com"),
    sign_in_count : 1,
    active : true
}; //인스턴스 생성

println!{"{}", my_data.email}; // geukggom@gmail.com 출력

 

 

구조체를 출력할 때 println!{"{}", my_data}; 으로 입력하면 `UserData` cannot be formatted with the default formatter 라는 에러가 뜰 것입니다. 구조체 전체 값을 출력하고 싶다면 

#[derive(Debug)]
struct UserData {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

 

이메일과 이름을 받아서 UserData 구조체를 반환하는 함수를 만들어보겠습니다. 구조체의 필드 이름과 입력하는 값의 변수 이름이 같다면 다음과 같이 생략 가능합니다.

fn build_user(email : String, username : String) -> UserData {
    UserData {
        email,
        username,
        active : true,
        sign_in_count : 1
    }
}

 

 

구조체 안의 값을 바꾸고 싶다면 다음과 같이 mutable로 선언해주어야 합니다.

let mut my_data = UserData {
    username : String::from("Geukggom"),
    email : String::from("geukggom@gmail.com"),
    sign_in_count : 1,
    active : true
};

my_data.email = String::from("none");
println!{"{}", my_data.email}; // none 출력

 

 

기존의 구조체 인스턴스는 그대로 내버려두되 값만 조금 바꾸어 새로운 인스턴스를 만들고 싶다면 다음과 같이 입력할 수 있습니다.

이를 구조체 갱신법(struct update syntax)이라 합니다.

let none_email = UserData {
    email : String::from("none"),
    ..my_data // 별도로 값을 입력한 필드 외 다른 모든 필드 값을 가져옴. 반드시 맨 마지막에 와야함.
};
println!{"{}", none_email.email}; // none 출력

이 갱신법의 특이사항이 있다면, 바로 값때 해당 값이 힙에 할당되어 있다면 소유권이 새로운 구조체로 이동한다는 점입니다.

let none_email = UserData {
    email : String::from("none"),
    ..my_data // 별도로 값을 입력한 필드 외 다른 모든 필드 값을 가져옴. 반드시 맨 마지막에 와야함.
};
println!{"{}", my_data.email}; // 에러 x
println!{"{}", my_data.username}; // 소유권이 none_email로 이동해서 에러 발생
println!{"{}", my_data.active}; // 에러 x

 

 

구조체 전체 값을 디버깅하고 싶다면 해당 구조체에 [derive(Debug)] 어노테이션을 추가합니다.

#[derive(Debug)]
struct UserData {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

let my_data {
	username: "geukggom",
    email: "none",
    sign_in_count: 1,
    active: true,
};

println!{"{:?}", my_data}; 
//UserData { username: "Geukggom", email: "none", sign_in_count: 1, active: true } 출력

<튜플 구조체>

: 튜플과 유사한 형태의 구조체로, 타입만 정의 가능하고 명명할 수는 없습니다.

struct Color(i32, i32, i32);
let black = Color(0,0,0);
println!{"{}", black.1}; // 0 출력

<유사 유닛 구조체(unit-like structs)>

: 어떠한 필드도 없는 구조체입니다. 특정한 타입의 트레잇(trait)을 구현해야 하지만, 유형 자체에 저장하려는 데이터가 없을 때 유용할 수 있습니다. 이 구조체는 10챕터에서 trait을 다룰 때 더 자세히 알아볼 예정입니다.


요약한 참조 링크 : https://rinthel.github.io/rust-lang-book-ko/ch05-01-defining-structs.html

 

 

반응형

'[Rust]' 카테고리의 다른 글

[Rust] 열거형(enum)  (0) 2023.08.01
[Rust] 구조체 - 메서드  (0) 2023.07.30
[Rust] 슬라이스(slices)  (0) 2023.07.27
[Rust] 참조자(References)와 빌림(Borrowing)  (0) 2023.07.26
[Rust] 소유권  (0) 2023.07.25