[Rust] #1 기초 문법

김지섭·2023년 6월 28일
0

세미콜론의 의미 (;)

  1. 문장의 종료
let x = 5; // 세미콜론으로 문장 종료
println!("Hello, world!"); // 세미콜론으로 문장 종료
  1. 값 반환
let x = (let y = 6); // 에러
let x = { let y = 6; y }; // 정상 작동

변수

타입 (Type)

타입 종류설명예시
부호 있는 정수형i8, i16, i32, i64, i128, isizelet x: i32 = 5;
부호 없는 정수형u8, u16, u32, u64, u128, usize (부호 없는 정수)let x: u32 = -5;
부동소수점형f32, f64let y: f64 = 6.4;
불리언형boollet t: bool = true;
문자형charlet c: char = 'z';
문자열&str, Stringlet s: &str = "hello"; let s: String = String::from("hello");
배열[T; N] (T는 타입, N은 길이)let a: [i32; 5] = [1, 2, 3, 4, 5];
튜플(T1, T2, ..., Tn) (Tn은 타입)let t: (i32, f64, u8) = (500, 6.4, 1);
슬라이스[T]let s: &[i32] = &a[1..3];
구조체structstruct Point { x: i32, y: i32 }
열거형enumenum Option<T> { Some(T), None }
포인터*const T, *mut T, Box<T>, Rc<T>, Arc<T>let r: *const i32 = &x;
함수fnfn add(x: i32, y: i32) -> i32 { x + y }

Struct

// 'Person'이라는 이름의 구조체를 정의합니다.
struct Person {
    name: String,
    age: u8,
    height: u8,
    weight: u8,
}

fn main() {
    // 'Person' 구조체의 인스턴스를 만듭니다.
    let person = Person {
        name: String::from("John"),
        age: 30,
        height: 175,
        weight: 70,
    };

    // 구조체의 필드에 접근합니다.
    println!("{} is {} years old, {} cm tall and weighs {} kg.", person.name, person.age, person.height, person.weight);
}

enum

enum Fruit {
    Apple,
    Banana,
    Mango,
    Kiwi,
}

fn main() {
    let myFruit = Fruit::Apple;
}

값의 비교는 추후에 설명할 matchfor-let을 참고하세요.

enum에 값 넣기

다른 언어들과는 다르게 rust의 enum에는 값을 넣을 수 있습니다.

enum Number {
    Integer(i32),
    Float(f64),
}

fn print_number(n: Number) {
    match n {
        Number::Integer(i) => println!("It's an integer: {}", i),
        Number::Float(f) => println!("It's a float: {}", f),
    }
}

fn main() {
    let int = Number::Integer(5);
    let float = Number::Float(5.5);

    print_number(int);
    print_number(float);
}

쓰기 제한

const

const는 상수를 선언하는 데 사용합니다. 상수는 프로그램의 실행 도중에 변경될 수 없는 값입니다. const로 선언된 상수는 항상 타입을 명시해야 하며, 컴파일 시점에 항상 값이 결정되어야 합니다.

const PI: f32 = 3.14159;

let

let은 불변(immutable) 변수를 선언하는 데 사용됩니다. Rust에서는 기본적으로 모든 변수가 불변입니다. 이는 변수에 저장된 값을 변경하려고 시도하면 컴파일러가 에러를 발생시키는 것을 의미합니다.

let x = 5;

let mut

let mut는 가변(mutable) 변수를 선언하는 데 사용됩니다. 가변 변수는 값을 변경할 수 있습니다. 변수를 가변으로 선언하려면, 선언 시에 mut 키워드를 사용해야 합니다.

let mut y = 5;
y = 6;

소유권 (Ownership)

  • Rust의 변수는 한번에 하나의 소유자(owner)가 존재한다.
  • 소유자 scope가 종료되면, 해당 값은 메모리에서 free된다.

아래 코드는 소유권이 이전되었을 때, 이전에 선언된 변수가 소유권을 박탈당하여 컴파일 에러가 나는 것을 보여줍니다.

fn main() {
    let s1 = String::from("hello");  // s1이 문자열에 대한 소유권을 갖습니다.
    let s2 = s1;         // 문자열의 소유권이 s2로 이동하였습니다.

    println!("{}", s1);  // [Error] s1은 소유권을 잃었기 때문입니다.
    println!("{}", s2);  // 이곳에서는 s2가 소유권을 가지고 있으므로 문제가 없습니다.
}

아래 코드는 함수에게 변수 전달을 통하여 소유권을 전달했을 때의 상황입니다.

fn main() {
    let s = String::from("hello");  // s가 소유권을 갖습니다.

    takes_ownership(s);  // s의 소유권이 함수로 이동하였습니다.
    println!("{}", s);  // [Error] s는 소유권을 잃었기 때문입니다.
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
    // some_string이 이 함수의 범위를 벗어나므로 자동으로 drop됩니다.
}

아래 코드는 함수가 호출자에게 변수를 return 하여, 소유권을 넘기는 상황입니다.

fn main() {
    let s = gives_ownership();  // s가 함수로부터 반환된 문자열의 소유권을 가집니다.
    println!("{}", s);  // s가 소유권을 가지고 있으므로 문제가 없습니다.
}

fn gives_ownership() -> String {
    let some_string = String::from("hello");
    some_string  // some_string의 소유권이 함수 호출자에게 이동됩니다.
}

소유권 이전 (Borrowing)

pub fn main(){
    let s1 = String::from("hello");

    // 함수로 넘겨줄 때, 참조자를 사용하면 소유권을 넘겨주지 않습니다.
    let len = calculate_length(&s1);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

제어문

if

if 문은 조건부 실행을 제공합니다. 조건이 참인 경우 해당 블록의 코드가 실행됩니다.

let number = 3;
if number < 5 {
    println!("condition was true");
} else {
    println!("condition was false");
}

if let

if let 구문은 패턴 매칭을 이용한 조건부 실행을 제공합니다. 값이 특정 패턴과 매치될 경우 해당 블록의 코드가 실행됩니다.

let option = Some(5);
if let Some(5) = option {
    println!("The value is five!");
}

match

match 구문은 여러 패턴에 대해 분기를 수행할 수 있습니다. match는 주어진 값을 여러 패턴과 비교하고, 첫번째로 일치하는 패턴의 코드 블록을 실행합니다.

let number = 4;
match number {
    1 => println!("one"),
    2 => println!("two"),
    3 => println!("three"),
    _ => println!("anything"),
}

반복문

loop

loop 구문은 무한 반복을 제공합니다. loop 블록 안의 코드는 계속해서 반복적으로 실행됩니다.

let mut counter = 0;
loop {
    counter += 1;
    if counter == 10 {
        break;
    }
}

while

while 구문은 조건이 참인 동안 반복을 수행합니다. 조건이 거짓이 될 때까지 블록 내의 코드를 반복해서 실행합니다.

let mut number = 3;
while number != 0 {
    println!("{}!", number);
    number -= 1;
}
println!("LIFTOFF!!!");

for-in

for-in 구문은 주어진 범위나 반복 가능한 아이템에 대해 반복을 수행합니다.

let arr = [10, 20, 30, 40, 50];
for element in arr.iter() {
    println!("the value is: {}", element);
}

0개의 댓글