๐Ÿฆ€Rust syntax

๋ณต์žกํ•˜์ง€๋งŒ ์•„๋ฆ„๋‹ต๋‹ค

2 minute read

์–ด๋А ์–ธ์–ด๋ฅผ ๋ฐฐ์šฐ๊ฑด ๊ธฐ๋ณธ๋ฌธ๋ฒ•์€ ๋น„์Šทํ•˜๋‹ค. Rust๋„ ์˜ˆ์™ธ๋Š” ์•„๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์—ญ์‹œ๋‚˜ ์ฃผ์˜ํ• ๋งŒํ•œ ์‚ฌํ•ญ ์œ„์ฃผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๋ คํ•œ๋‹ค.

Scala ํƒ€์ž…๊ณผ Compound ํƒ€์ž…

Rust๋Š” ํƒ€์ž…์ง€ํ–ฅ์  ์–ธ์–ด์ด๋ฉฐ scala ํƒ€์ž…๊ณผ compount ํƒ€์ž…์ด ์žˆ๋‹ค.

scala๋Š” ๋‹ค๋ฅธ ์–ธ์–ด์˜ primitive ํƒ€์ž…๊ณผ ์˜๋ฏธ๊ฐ€ ๋น„์Šทํ•˜๋ฉฐ rust๊ฐ€ ์ž๋™์œผ๋กœ stack memory์— ํ• ๋‹น์„ ํ•œ๋‹ค.
compound๋Š” tuple์ด๋‚˜ array๊ฐ™์€ ๋ณตํ•ฉ์ฒด๋กœ heap memory์— ํ• ๋‹น๋œ๋‹ค.

๋ณ€์ˆ˜์˜ ์„ ์–ธ : let๊ณผ mut

let a = 5;  
a = 6;    // compile error  
  
let mut b = 5;  
b = 6;    // Okay  

let์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๋ณ€์ˆ˜(?)์˜ ์„ ์–ธ์ด๋‹ค. (const๊ฐ€ ์ƒ์ˆ˜๋ฅผ ์œ„ํ•ด์„œ ๋”ฐ๋กœ ์žˆ๋‹ค๊ณ ํ•ด์„œ ์ด์ƒํ•œ ์„ค๋ช…์ด ๋˜์–ด๋ฒ„๋ ธ๋‹ค)
๊ธฐ๋ณธ์ ์œผ๋กœ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ฒ˜๋Ÿผ ๋ถˆ๋ณ€์„ฑ์„ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜๋ ค๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

let์— mut๋ฅผ ๋ถ™์ด๋ฉด ๋น„๋กœ์†Œ ๋ณ€์ˆ˜๊ฐ€ ๋˜๋Š”๋ฐ mutable์ด๋ž€ ๋œป์ด๋‹ค.
์ •์ˆ˜ํ˜•์˜ ๊ธฐ๋ณธํ˜•์€ 32bit๋กœ ํƒ€์ž…์„ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ •์˜๋œ๋‹ค.

let mut a = 2147483647;    // 32bit  
a = a + 1;    // compile error  

a๋Š” ํƒ€์ž…์„ ์ •์˜ํ•˜์ง€์•Š์•„ ๊ธฐ๋ณธ์ธ 32bit์ด๋‹ค. compileํ•ด๋ณด๋ฉด compiler๋Š” ๋ณ€์ˆ˜์˜ overflow๋‚˜ round robin์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. warning์ด ์•„๋‹ˆ๋ผ compile error๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋งค์šฐ ์—„๊ฒฉํ•˜๋‹ค.

let mut a:i64 = 2147483647;  
a = a + 1;    // Okay  

๋ณ€์ˆ˜ ๋’ค์— ์œ„์™€ ๊ฐ™์ด ํƒ€์ž… ์ง€์ •์„ ํ•  ์ˆ˜ ์žˆ๊ณ  a๋Š” 64๋น„ํŠธ์ด๋ฏ€๋กœ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

let x = 2.0;    // 64bit  
let y:f32 = 3.0;  

๋ฐ˜๋Œ€๋กœ ์‹ค์ˆ˜ํ˜•์˜ ๊ฒฝ์šฐ 64bit๊ฐ€ ๊ธฐ๋ณธ์ด๋‹ค.
C์–ธ์–ด์—์„œ double์ด ๊ธฐ๋ณธ์ด๊ณ  ๋น ๋ฅธ ๊ฒƒ๊ณผ ๋น„์Šทํ•ด๋ณด์ธ๋‹ค. ์ปดํ“จํ„ฐ๊ณตํ•™์ ์œผ๋กœ ๋‹น์—ฐํ•œ ์ด์•ผ๊ธฐ์ด๋‹ค.

let months = ["Jan", "Feb"];  
println!("{}", months[3]);    // compile error  

๋จผ์ € ์„ค๋ช…์ด ๋น ์ง„ ๋ถ€๋ถ„์ด ์žˆ์—ˆ๋Š”๋ฐ ์ € { }๋Š” ์˜ˆ์ƒํ•˜๋“ฏ placeholder์ด๋‹ค.
(like %d in C language)
๊ทธ๋ฆฌ๊ณ  ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ด ์ฝ”๋“œ๋Š” [3]์—์„œ overflow๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ compile error๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ฆ‰, ์ž˜๋ชป๋œ memory access๋ฅผ ๋ฏธ๋ฆฌ ๋ง‰๋Š”๋‹ค.

ํ•˜๋ฉด ํ• ์ˆ˜๋ก ๋ฌธ๋ฒ•๋ณด๋‹ค๋Š” rust๊ฐ€ ์–ผ๋งˆ๋‚˜ ์—„๊ฒฉํ•œ์ง€์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋˜์–ด๊ฐ„๋‹ค.
ํ•˜์ง€๋งŒ ์ง€์ €๋ถ„ํ•˜์ง€์•Š๊ณ  ๋ชจ๋˜ํ•˜๋‹ค.

ํ•จ์ˆ˜

fn main() {  
    another_function(3);  
}  
  
fn another_function(x:i32) -> i32 {  
    println!("x={}", x);  
    x + 1  
}  

ํ•จ์ˆ˜๊ฐ€ ๋ฏธ๋ฆฌ ์•ž์— ์„ ์–ธ๋  ํ•„์š”๊ฐ€ ์—†๋‹ค(๋ชจ๋˜ํ•˜์ง€?)

๊ทธ๋ฆฌ๊ณ  return value๋Š” ๋งˆ์ง€๋ง‰์€ expression์ด๋‹ค. ์„ธ๋ฏธ์ฝœ๋ก ์„ ๊นŒ๋จน์€ ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
(์˜คํžˆ๋ ค ;๋ฅผ ๋ถ™์ด๋ฉด expression์ด ์•„๋‹Œ statement๊ฐ€ ๋˜์–ด์„œ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค)

๊ทธ๋ฆฌ๊ณ  ๋ฌผ๋ก  ๋‹ค๋ฅธ ์–ธ์–ด์ฒ˜๋Ÿผ ๋ช…์‹œ์ ์œผ๋กœ return์„ ์“ธ์ˆ˜๋„ ์žˆ๋‹ค.

Tuple

tuple์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋ณตํ•ฉ์ ์ธ ํƒ€์ž…์ด ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.
(Modern C++ ๋“ฑ์—์„œ๋„ ์ œ๊ณต๋˜๋Š” ๊ทธ tuple์ด๋‹ค)

fn main() {  
    let x: (i32, f64, u8) = (500, 6.4, 1);  
  
    let five_hundred = x.0;  
    let six_point_four = x.1;  
    let one = x.2;  
}  

๊ทธ๋ฆฌ๊ณ  ๋ฐฐ์—ด,

fn main() {  
    let a = [1,2,3,4,5];  
    for element in a.iter() {  
        if element == 3 {  
            break;  
        }  
    }  
}  

๋ฐฐ์—ด์—๋Š” method์ธ iter()๊ฐ€ ์žˆ์Œ๊ณผ if, while ๋“ฑ์˜ ์กฐ๊ฑด์—๋Š” ๊ด„ํ˜ธ๊ฐ€ ์—†์Œ์„ ์ฃผ๋ชฉํ•˜์ž.
(์žˆ์œผ๋ฉด ์˜คํžˆ๋ ค warning์ด ๋‚œ๋‹ค)

์™œ๋ƒ๋ฉด ์—ฌ๊ธฐ์„œ if๋Š” expression์ด๋‹ค. ๋”ฐ๋ผ์„œ let๊ณผ ํ•จ๊ป˜ ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

let number = if condition {  
        5  
    } else {  
        6  
    };  

์‚ผํ•ญ์—ฐ์‚ฐ์ž๋ณด๋‹ค ๋” ๊น”๋”ํ•ด๋ณด์ธ๋‹ค.
expression์˜ ๊ฐœ๋…์„ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ์˜ˆ์ œ๋ฅผ ํ•˜๋‚˜ ๋” ์‚ดํŽด๋ณด์ž.

fn main() {  
    let x = 5;  
  
//    let x = (let y = 6); // compile error  
  
    let y = {  
        let x = 3;  
        x + 1  
    };  
  
    println!("The value of y is: {}", y);  
}  

๊ตฌ์กฐ์ฒดโ€ฆ์‚ฌ์‹ค์€ ํด๋ž˜์Šค

์ด๋ฒˆ์—๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์•Œ์•„๋ณธ๋‹ค.
(method๋„ ์žˆ์œผ๋‹ˆ ์‚ฌ์‹ค์ƒ ํด๋ž˜์Šค๋‹ค)

fn main() {  
    struct User {  
        username: String,  
        email: string,  
        sign_in_count: u64,  
        active: bool  
    }  
  
    impl User {  
        fn get_active(&self) -> bool {     // first parameter must be &self  
            self.active  
        }  
    }  
  
    let user1 = User {  
        email: String::from("example@xyz.com");  
        username: String::from("hoo");  
        active: true,  
        sign_in_count: 1  
    };  
  
    let user2 = User {  
        active: false,  
        ..user1    // email, username => move from user1  
    }  
  
    println!("{}", user1.email);    // compile error => user1.email move  
}  

method์˜ ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ &self๋ฅผ ๋ฐ›๋Š” ์ 
(C++์˜ this์™€ ๊ฐ™๋‹ค. ์—ฌ๋Ÿฌ๋ชจ๋กœ C++ ์œ ์ €๊ฐ€ ํŒŒ์•…ํ•˜๊ธฐ ์‰ฌ์šด ์–ธ์–ด๊ฐ™๋‹ค)

method๊ฐ€ impl๋กœ ๋”ฐ๋กœ ๋–จ์–ด์ ธ์žˆ๋Š” ์ 
(C++์—์„œ ์„ ์–ธ๊ณผ ๊ตฌํ˜„์„ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•ด๋ณด์ธ๋‹ค. data structure๋งŒ ๊น”๋”ํ•˜๊ฒŒ ๋”ฐ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค)