Rust 6

코와->코어·2022년 5월 8일
0
  1. Enums and Pattern Matching

enum

enum IpAddrKind {
    V4,
    V6,
}

fn main() {
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;

    route(IpAddrKind::V4);
    route(IpAddrKind::V6);
}

fn route(ip_kind: IpAddrKind) {}

struct IpAddr {
        kind: IpAddrKind,
        address: String,
    }

let home = IpAddr {
        kind: IpAddrKind::V4,
        address: String::from("127.0.0.1"),
};

let loopback = IpAddr {
        kind: IpAddrKind::V6,
        address: String::from("::1"),
};


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"));
}

the name of each enum variant that we define also becomes a function that constructs an instance of the enum. That is, IpAddr::V4() is a function call that takes a String argument and returns an instance of the IpAddr type. We automatically get this constructor function defined as a result of defining the enum.

enum안에는 어떤 자료형이든지 넣을 수 있다

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {}
struct QuitMessage; // unit struct
struct MoveMessage {
    x: i32,
    y: i32,
}
struct WriteMessage(String); // tuple struct
struct ChangeColorMessage(i32, i32, i32); // tuple struct

fn main() {}

이렇게 struct로 선언할 수도 있지만, 그러면 enum처럼 이것들을 다 하나의 타입으로 받는 함수를 만들기가 쉽지가 않음

impl 키워드로 enum에도 메소드 정의가능(sturct와 공통점)

fn main() {
    enum Message {
        Quit,
        Move { x: i32, y: i32 },
        Write(String),
        ChangeColor(i32, i32, i32),
    }

    impl Message {
        fn call(&self) {
            // method body would be defined here
        }
    }

    let m = Message::Write(String::from("hello"));
    m.call();
}

Option Enum
표준라이브러리에 정의된 enum


fn main() {
	enum Option<T> {
    	None,
    	Some(T),
	}
    
    let some_number = Some(5);
    let some_string = Some("a string");

    let absent_number: Option<i32> = None;

}
fn main() {
    let x: i8 = 5;
    let y: Option<i8> = Some(5);

    let sum = x + y;
}

In short, because Optio<\T> and T (where T can be any type) are different types, the compiler won’t let us use an Option value as if it were definitely a valid value. For example, this code won’t compile because it’s trying to add an i8 to an Option i8과 Option은 서로 다른 타입으로 인식해서 컴파일 안 됨

match

Patterns can be made up of literal values, variable names, wildcards, and many other things
패턴에 따라 다른 코드블록 실행시켜줌

enum Coin {
  Penny,
  Nickel,
  Dime,
  Quarter,
}

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
      }
  }

}

fn main() {}

러스트에서 match는 모든 가능한 경우를 다 다뤄줘야 함

fn main() {
let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
other => move_player(other),
}

match diceroll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
=> reroll(),
_ => (),
}

fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn move_player(num_spaces: u8) {}

}

catch-all 은 맨 마지막에 써야 함
위처럼 함수로 인자 받기도 싫으면 _, 사용하면 됨

if let

하나의 패턴에만 코드 실행하고 나머지는 무시하고 싶을 때 사용

fn main() {
let coin = Coin::Penny;
let mut count = 0;
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
}

profile
풀스택 웹개발자👩‍💻✨️

0개의 댓글