시뻘건 개발 도전기

러스트 13 - 구조체 #1 본문

프로그래밍/RUST

러스트 13 - 구조체 #1

시뻘건볼때기 2019. 3. 10. 15:38
반응형



"Structure"라고 불리는 구조체는 여러가지의 관련된 값을 함께 이름을 지정(naming)하고 package화 할 수 있는 사용자의 커스텀 데이터 형식이다.


구조체는 <변수와 타입 #2> 포스팅(https://maeng-dev.tistory.com/9)에서 다룬 튜플과 비슷하게 서로 다른 타입으로 구성될 수 있다.

하지만 각각의 구성 요소의 이름을 지정하여 값의 의미를 분명하고 명확아게 알 수 있다. 이 이점 덕분에 튜플보다 다루기 쉽다.



struct Family {    // 구조체 정의

    // 필드

    mother: String,

    father: String,

    son: String,

    number: u64,

}


구조체를 정의할 때, struct 키워드를 사용하고 구조체의 naming을 하면 된다. (name의 첫 글자는 대문자로 하자.)

이 구조체에 접근하여 사용하기 위해서는 구조체의 인스턴스(instance)를 생성해야 한다.

필드의 format은 다음과 같다.

key : value = 필드 명 : 필드 값

(참고로 필드의 순서는 상관하지 않아도 된다. 순서대로 저장되는 녀석이 아니니까.)

필드레 접근할 때, "Dot-notation"을 사용하면 된다.

예를 들어, son 필드에 접근을 원한다면 "family.son"으로 접근하면 된다.


fn main() {

    struct Family {

        mother: String,

        father: String,

        son: String,

        count: u64,

    }


    let our_family = Family {

        mother: String::from("W"),

        father: String::from("M"),

        son: String::from("MAENG"),

        count: 3,

    };

    println!("mother : {}", our_family.mother);

    println!("father : {}", our_family.father);

    println!("son : {}", our_family.son);

    println!("count : {}", our_family.count);

}





1. 구조체 특성

  • 필드 명과 필드 값에 저장하려고하는 변수 명이 같을 때 간결하게 짤 수 있다.


// 전역 구조

struct Family {

    mother: String,

    father: String,

    son: String,

    count: u64,

}


fn main() {

    let our_family = Family {

        mother: String::from("W"),

        father: String::from("M"),

        son: String::from("MAENG"),

        count: 3,

    };


    let name = String::from("kim");

    let count = 4;

    let your_family = nothing_family(name, count);


    println!("mother : {}", our_family.mother);

    println!("father : {}", our_family.father);

    println!("son : {}", our_family.son);

    println!("count : {}", our_family.count);


    println!("=================================");


    println!("mother : {}", your_family.mother);

    println!("father : {}", your_family.father);

    println!("son : {}", your_family.son);

    println!("count : {}", your_family.count);

}


// 구조체 반환

fn nothing_family(son: String, count: u64) -> Family {

    Family {

        mother: String::from("Keey"),

        father: String::from("Sam"),

        son,

        count,

    }

}


좋아하지 않는 방법이지만... 아직 rust가 서툴기 때문에 어쩔 수 없이 전역을 사용했다..ㅠㅠ



매개변수 명과 구조체의 필드 명이 겹치면 상당히 귀찮고 심지어 이름이 길 수록 우리는 복붙이 남발 할 것이다...(뜨끔)

이런 자질구리한 불편한 점과 소소한 코드 중복(?)을 최대한 상쇄시켜주었다.


  • 필드 빌림(borrowing)

구조체 갱신법(Struct Update Syntax)는 위 특성 보다 더 좋은 특성을 띄는 것 같다. 필드가 많은 구조체를 여러 인스턴스를 생성할 때 사용하면 굉장히 좋은 시너지를 발휘할 것 같은 낌!!!!


struct Family {

    mother: String,

    father: String,

    son: String,

    count: u64,

}


fn main() {

    let name = String::from("kim");

    let count = 4;

    let your_family = nothing_family(name, count);


    let our_family = Family {

        son: String::from("MAENG"),

        count: 3,

        ..your_family    // 나머지 값은 your_family 인스턴스에서 가지고 온다.

    };


    println!("mother : {}", our_family.mother);

    println!("father : {}", our_family.father);

    println!("son : {}", our_family.son);

    println!("count : {}", our_family.count);

}


fn nothing_family(son: String, count: u64) -> Family {

    Family {

        mother: String::from("Keey"),

        father: String::from("Sam"),

        son,

        count,

    }

}




  • 튜플 구조체
튜플 구조체는 각 필드의 데이터 타입을 정의 할 수 있지만 naming은 할 수 없다.

fn main() {

    struct Family(String, String, String);


    let father = String::from("father");

    let mother = String::from("mother");

    let son = String::from("son");


    // we 인스턴스 생성

    let we = Family(father, mother, son);


    println!("we : {} + {} + {}", we.0, we.1, we.2);

}









만약 구조체에서 각 필드의 타입이 String 타입이 아닌, String Slice 타입(&str)을 사용하게 되면 어떤 현상이 일어 날까?

다만, 구조체의 인스턴스가 모든 데이터를 소유하고 유효하기를 원하냐 원하지 않느냐의 차이...

즉, 이 것을 원하니 String 타입을 사용 한 것.

그리고 또 하나.

나중에 배울 "라이프 타임(LifeTime)"이라고 하는 녀석이 있는데, 이 녀석은 구조체가 존재하는 동안 참조하는 데이터를 계속 유효할 수 있도록 한다.

만약, String Slice 타입을 사용하고 싶다면 이 라이프 타임을 지정해주어야 한다는 이야기인 것 같다.

천천히 알아가보자...ㅎㅎㅎㅎㅎ

반응형
Comments