728x90
c,c++의 구조체(struct)랑 열거형(enum)과 많이 다른가? 튜플과 또 다른점은?
1. 구조체 Struct
정의 및 인스턴트화
서로 연관된 필드 및 데이터를 묶는 방법
struct struct_name {
value_name: value_type,
...,
}
- c/c++이랑 큰 차이없다. 구조체 선언 하고 구조체 내부 속성에 타입을 설정하면 된다. 값은 "."을 통해서 사용할수 있다.
- 가변적으로 사용하려면 let mut st: struct_name; 이런식으로 선언하면 된다. 구조체 내 특정 값만 가변적으로 사용할순 없다.
필드 초기화 축약법
fn build_user(email: String, username: String) -> User {
User {
active: true,
username, // username: username 과 같음
email, // email: email 과 같음
sign_in_count: 1,
}
}
// 기존 인스턴스 이용
fn test() {
let user1 = User {/* 생략 */}
let user2 = User {
email: String::from("another@example.com"),
..user1 // 나머지 값은 user1과 동일
};
}
- js 에서도 비슷하게 썼던거같다.
- 아래 방식으로 기존 인스턴스를 이용해서 새롭게 만드는 경우 소유권이 이전될 수 있다.
- &str 을 사용해서 소유권을 갖지 않는 데이터를 저장할수 있지만 lifetime을 지정해야 사용할수 있다.
- -> 이후에 나오므로 어떻게 쓰는지 아직 잘 모른다.
구조체 여러가지 사용법
// tuple structs
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
// unit-like structs
struct AlwaysEqual;
fn main() {
let subject = AlwaysEqual;
}
- 필드 이름을 적지 않고 쓰는 경우엔 tuple structs를 사용한다.
- RGB나 x,y,z 처럼 묶어서 사용할 때 유용하다. struct Color{R: i32, G:i32, B:i32}; 보다 struct Color(i32,i32,i32);가 좀더 사용하기 편할듯하다. black.R 과 같이 개별로는 못쓰긴 하겠지만 말이다.
- 필드가 없는 유사 유닛 구조체는 어디에 쓰는지 잘 모르겠다.
2. 메서드
impl 이라는 키워드를 사용해서 구조체에서 사용할수 있는 메서드를 구현할수 있다.
- rust엔 클래스가 없다..! 러스트는 객체지향언어가 아닌듯하다.
3. 열거형
enumerations, enums
어떤 값이 여러 개의 가능한 값의 집합 중의 하나
- 말이 좀 어려운데 선택지를 묶어놓는다고 보면 된다.
fn main() {
enum IpAddr {
V4(String),
V6(String),
}
let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));
}
- enum 을 정의하고 실제도 인스턴스를 만들때 kind 안에 선택지를 골라서 작성하면된다.
열거형의 장점
- 각 배리언트는 다른 타입과 다른 양의 연관된 데이터를 가질 수 있다 .데이터가 아예 없어도 되고 구조체가 들어가도된다.
- 위의 코드에서 V4(u8,u8,u8,u8), V6(String) 으로 설정할 수 있다. 해당 enum 값을 선택할때 데이터만 잘 넣어서 사용하면된다.
Option
enum Option<T> {
None,
Some(T),
}
값이 있거나 없을 수 있는 상황을 나타냄
- Rust 에선 Option 가 아닌 타입이면 항상 값이 있다고 보장할수 있다.
- Option<T> 을 일반 타입(T)으로 사용하려면 변환이 필요하다.
- Swift의 Optional 생각하면 될 듯 하다.
- c나 파이썬에선 if (ptr == NULL) 이나 if data == None: 등을 사용해서 값이 없는 예외를 처리해야한다. (해당 변수가 NULL 값인지 항상 확인해야한다.)
4. 제어 흐름
match
#[derive(Debug)] // so we can inspect the state in a minute
enum UsState {
Alabama,
Alaska,
// --생략--
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
}
}
}
- match는 c의 switch와 비슷하다.
enum Option<T> {
None,
Some(T),
}
fn check_option(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => {
// do something
Some(i+1);
},
}
}
- 위의 Option<T> 도 match를 사용해서 처리할수 있다.
match 마지막에 변수 이름을 적으면 명시하지 않은 값을 처리할수있다.
- switch의 default와 같다.
- 변수이름을 _(underbar)로 사용하면 해당 변수를 사용하지 않는다는 뜻이다.
if let
하나의 패턴만 매칭시키고 나머지 패턴은 무시하는 방법
// match
fn main() {
let x = 32;
match x {
32 => { println!("hello"); },
_ => {},
}
}
// if let
fn main() {
let x = 32;
if let 32 = x { println!("hello"); }
}
- 위와 같이 딱 하나의 패턴만 쓰고 나머지는 필요없는 경우에 사용한다.
- if let에 else 를 사용해서 match와 똑같이 만들수 있다.
생각해 볼 것
// if let 2
fn main() {
let x = 32;
if let x = 32 { println!("hello,{}",x); }
if let x = 99 { println!("hello??,{}",x); }
if let 32 = x { println!("hello????,{}",x); }
if let 99 = x { println!("hello??????,{}",x); }
}
// output
hello,32
hello??,99
hello????,32
- 실행 결과를 분석해보자
- if let x = 32 { println!("hello,{}",x); }
- hello, 32가 출력된다.
- if 문에서 사용할 변수 x(바로 위에서 할당한 x 와 다름)에 32를 할당하고 println 문을 실행한다.
- if let x = 99 { println!("hello??,{}",x); }:
- hello??, 99가 출력된다.
- if 문에서 사용할 변수 x(위에서 할당한 x 와 다름)에 99를 할당하고 println 문을 실행한다.
- if let 32 = x { println!("hello????,{}",x); }
- hello????, 32가 출력된다.
- if let 문에서 x가 32인지 확인한다. x ==32 이므로 println 문을 실행한다.
- if let 99 = x { println!("hello??????,{}",x); }
- 출력되지 않는다.
- if let 문에서 x가 99인지 확인한다. x == 32 이므로 println 문을 실행하지 않는다.
- if let x = 32 { println!("hello,{}",x); }
- 아래 글은 반박 가능한 패턴에 관련한 내용인데 읽어보면 좋을듯하다. 어려우니 나중에 다시 읽어 봐야지 ㅎㅎ
https://doc.rust-kr.org/ch05-00-structs.html
https://doc.rust-kr.org/ch06-00-enums.html
'STUDY > Rust' 카테고리의 다른 글
Rust - 9. 컬렉션(vector, string, hash map) (0) | 2024.02.20 |
---|---|
Rust - 8. 패키지, 크레이트, 모듈 (0) | 2024.02.19 |
Rust - 6. 소유권 (0) | 2024.02.16 |
Rust - 5. 문법/함수, 주석, 제어흐름문 (0) | 2024.02.15 |
Rust - 4. 문법/변수, 데이터 타입 (0) | 2024.02.14 |