{"id":9772,"date":"2025-01-26T15:52:27","date_gmt":"2025-01-26T06:52:27","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=9772"},"modified":"2025-02-04T15:17:22","modified_gmt":"2025-02-04T06:17:22","slug":"rust-%ea%b8%b0%ec%b4%88-%ea%b0%95%ec%a2%8c","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=9772","title":{"rendered":"Rust \uae30\ucd08 \uac15\uc88c"},"content":{"rendered":"<h1>Rust \uae30\ucd08 \uac15\uc88c<\/h1>\n<p>\ub7ec\uc2a4\ud2b8\uc758 \ubaa8\ub4e0 \ubb38\ubc95\uc744 \uc124\uba85\ud558\uba74 \ub108\ubb34 \uae38\uc5b4\uc9c0\ubbc0\ub85c, \uac00\uc7a5 \uae30\ucd08\uc801\uc778 \ub0b4\uc6a9\ub9cc \uc791\uc131\ud569\ub2c8\ub2e4.<\/p>\n<h2>1. \uc2dc\uc791\ud558\uae30<\/h2>\n<h3>1.1 Hello World<\/h3>\n<pre><code class=\"language-rust\">fn main() {\n    println!(&quot;Hello World!&quot;);\n}<\/code><\/pre>\n<p>\uccab \ubc88\uc9f8 Rust \ud504\ub85c\uadf8\ub7a8\uc785\ub2c8\ub2e4. <code>main<\/code> \ud568\uc218\ub294 \ud504\ub85c\uadf8\ub7a8\uc758 \uc9c4\uc785\uc810\uc774\uba70, <code>println!<\/code> \ub9e4\ud06c\ub85c\ub97c \uc0ac\uc6a9\ud574 \ud14d\uc2a4\ud2b8\ub97c \ucd9c\ub825\ud569\ub2c8\ub2e4.<\/p>\n<h3>1.2 \uc8fc\uc11d<\/h3>\n<pre><code class=\"language-rust\">\/\/ \ud55c \uc904 \uc8fc\uc11d\n\/* \uc5ec\ub7ec \uc904 \n   \uc8fc\uc11d *\/<\/code><\/pre>\n<h3>1.3 \uc11c\uc2dd\ud654\ub41c \ucd9c\ub825<\/h3>\n<pre><code class=\"language-rust\">println!(&quot;{} \ub354\ud558\uae30 {} \uc740 {}&quot;, 1, 2, 1 + 2);\nprintln!(&quot;{:?}&quot;, (3, 4)); \/\/ \ub514\ubc84\uadf8 \ucd9c\ub825\nprintln!(&quot;{0}\uc57c \uc598\ub294 \ub0b4 \uce5c\uad6c {1}\uc57c. {1}\uc57c \uc774\ucabd\uc740 {0}\uc57c&quot;, &quot;\uc601\ud76c&quot;, &quot;\ucca0\uc218&quot;);<\/code><\/pre>\n<h2>2. \uae30\ubcf8 \uc790\ub8cc\ud615<\/h2>\n<h3>2.1 \uc22b\uc790\ud615<\/h3>\n<pre><code class=\"language-rust\">let i: i32 = 42;      \/\/ \uc815\uc218\nlet f: f64 = 3.14;    \/\/ \ubd80\ub3d9\uc18c\uc218\uc810\nlet b: bool = true;   \/\/ \ubd88\ub9ac\uc5b8<\/code><\/pre>\n<h3>2.2 \ubcf5\ud569 \uc790\ub8cc\ud615<\/h3>\n<pre><code class=\"language-rust\">\/\/ \ud29c\ud50c\nlet tuple = (1, &quot;hello&quot;, 3.14);\n\n\/\/ \ubc30\uc5f4\nlet array = [1, 2, 3, 4, 5];<\/code><\/pre>\n<h3>2.3 \uce90\uc2a4\ud305<\/h3>\n<pre><code class=\"language-rust\">let decimal = 65.4321_f32;\nlet integer = decimal as u8;     \/\/ f32\ub97c u8\ub85c \uce90\uc2a4\ud305\nlet character = integer as char; \/\/ u8\uc744 char\ub85c \uce90\uc2a4\ud305\n\n\/\/ \uc22b\uc790\ud615 \uac04\uc758 \uce90\uc2a4\ud305\nlet a = 15;                \/\/ i32\nlet b = a as i64;          \/\/ i32\ub97c i64\ub85c \uce90\uc2a4\ud305\nlet c = 256.3_f32 as i32;  \/\/ f32\ub97c i32\ub85c \uce90\uc2a4\ud305<\/code><\/pre>\n<h3>2.4 \ud0c0\uc785 \uc811\ubbf8\uc0ac<\/h3>\n<pre><code class=\"language-rust\">let x = 42u8;        \/\/ u8 \ud0c0\uc785\nlet y = 123_456i32;  \/\/ i32 \ud0c0\uc785\nlet z = 3.14f64;     \/\/ f64 \ud0c0\uc785\nlet big = 1_000_000; \/\/ \uac00\ub3c5\uc131\uc744 \uc704\ud55c \uc5b8\ub354\uc2a4\ucf54\uc5b4 \uc0ac\uc6a9<\/code><\/pre>\n<h3>2.5 \ud0c0\uc785 \ucd94\ub860<\/h3>\n<pre><code class=\"language-rust\">let inferred_type = 42; \/\/ i32\ub85c \uc790\ub3d9 \ucd94\ub860\nlet float = 3.0;        \/\/ f64\ub85c \uc790\ub3d9 \ucd94\ub860\nlet v = vec![1, 2, 3];  \/\/ Vec&lt;i32&gt;\ub85c \uc790\ub3d9 \ucd94\ub860\n\n\/\/ \ubb38\ub9e5 \uae30\ubc18 \ud0c0\uc785 \ucd94\ub860\nlet elem = v[0];        \/\/ v\uc758 \uc694\uc18c \ud0c0\uc785\uc5d0 \ub530\ub77c \ucd94\ub860<\/code><\/pre>\n<h3>2.6 \ud0c0\uc785 \uc54c\ub9ac\uc5b4\uc2f1<\/h3>\n<pre><code class=\"language-rust\">type Distance = i32;\ntype Coordinates = (i32, i32);\n\n\/\/ \ud0c0\uc785 \uc54c\ub9ac\uc5b4\uc2a4 \uc0ac\uc6a9\nlet distance: Distance = 5;\nlet position: Coordinates = (10, 20);\n\n\/\/ \ubcf5\uc7a1\ud55c \ud0c0\uc785\uc5d0 \ub300\ud55c \uc54c\ub9ac\uc5b4\uc2f1\ntype Result&lt;T&gt; = std::result::Result&lt;T, std::io::Error&gt;;\ntype PlayerMap = HashMap&lt;String, Vec&lt;(i32, i32)&gt;&gt;;<\/code><\/pre>\n<h2>3. \ubcc0\uc218\uc640 \uac00\ubcc0\uc131<\/h2>\n<pre><code class=\"language-rust\">let x = 5;        \/\/ \ubd88\ubcc0 \ubcc0\uc218\nlet mut y = 10;   \/\/ \uac00\ubcc0 \ubcc0\uc218\ny = 15;           \/\/ \uac12 \ubcc0\uacbd \uac00\ub2a5<\/code><\/pre>\n<h2>4. \ud568\uc218<\/h2>\n<h3>\ud45c\ud604\uc2dd (expression)<\/h3>\n<p>\ud45c\ud604\uc2dd\uc740 \uac12\uc744 \ubc18\ud658\ud558\ub294 \ucf54\ub4dc\uc785\ub2c8\ub2e4.<br \/>\n\ud45c\ud604\uc2dd\uc740 \uc138\ubbf8\ucf5c\ub860(;)\uc73c\ub85c \ub05d\ub098\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<br \/>\n\ub9c8\uc9c0\ub9c9 \ud45c\ud604\uc2dd\uc758 \uac12\uc774 \ud568\uc218\uc758 \ubc18\ud658\uac12\uc774 \ub429\ub2c8\ub2e4.<\/p>\n<h3>\ud568\uc218 \uae30\ucd08<\/h3>\n<pre><code class=\"language-rust\">fn add(a: i32, b: i32) -&gt; i32 {\n    a + b              \/\/ \uc554\uc2dc\uc801 \ubc18\ud658\n    \/\/ return a + b;   \/\/ \uba85\uc2dc\uc801 \ubc18\ud658\n}\n\nfn main() {\n    let result = add(5, 3);\n    println!(&quot;\uacb0\uacfc: {}&quot;, result);\n}<\/code><\/pre>\n<h2>5. \uc81c\uc5b4\ubb38<\/h2>\n<h3>5.1 if \ud45c\ud604\uc2dd<\/h3>\n<pre><code class=\"language-rust\">let number = 5;\nif number &lt; 10 {\n    println!(&quot;10\ubcf4\ub2e4 \uc791\uc74c&quot;);\n} else {\n    println!(&quot;10\ubcf4\ub2e4 \ud06c\uac70\ub098 \uac19\uc74c&quot;);\n}<\/code><\/pre>\n<h3>5.2 let if \ud45c\ud604\uc2dd<\/h3>\n<pre><code class=\"language-rust\">let condition = true;\nlet number = if condition {\n    5\n} else {\n    6\n};  \/\/ \uc138\ubbf8\ucf5c\ub860 \ud544\uc694\n\n\/\/ \ubaa8\ub4e0 \ubd84\uae30\uac00 \uac19\uc740 \ud0c0\uc785\uc774\uc5b4\uc57c \ud568\nlet number = if condition {\n    5   \/\/ i32\n} else {\n    6   \/\/ i32\n};  \n\n\/\/ \ub2e4\ub978 \ud0c0\uc785\uc744 \ubc18\ud658\ud558\uba74 \ucef4\ud30c\uc77c \uc5d0\ub7ec\nlet number = if condition {\n    5       \/\/ i32\n} else {\n    &quot;six&quot;   \/\/ &amp;str - \ucef4\ud30c\uc77c \uc5d0\ub7ec!\n};<\/code><\/pre>\n<h3>5.2 if let \ud45c\ud604\uc2dd<\/h3>\n<pre><code class=\"language-rust\">\/\/ Option \uac12\uc744 \ucc98\ub9ac\ud560 \ub54c \uc720\uc6a9\nlet some_value = Some(3);\nif let Some(x) = some_value {\n    println!(&quot;\uac12\uc740 {}&quot;, x);\n} else {\n    println!(&quot;\uac12\uc774 \uc5c6\uc74c&quot;);\n}\n\n\/\/ Result \uac12\uc744 \ucc98\ub9ac\ud560 \ub54c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\nlet result = Ok(5);\nif let Ok(value) = result {\n    println!(&quot;\uc131\uacf5: {}&quot;, value);\n}\n\n\/\/ \uc5f4\uac70\ud615(enum) \ub9e4\uce6d\uc5d0\ub3c4 \uc720\uc6a9\nenum Color {\n    Red,\n    Blue,\n    Green\n}\nlet color = Color::Red;\nif let Color::Red = color {\n    println!(&quot;\ube68\uac04\uc0c9\uc785\ub2c8\ub2e4&quot;);\n}<\/code><\/pre>\n<h3>5.3 \ubc18\ubcf5\ubb38<\/h3>\n<pre><code class=\"language-rust\">\/\/ for \ubc18\ubcf5\ubb38\nfor i in 0..5 {\n    println!(&quot;{}&quot;, i);\n}\n\n\/\/ while \ubc18\ubcf5\ubb38\nlet mut n = 0;\nwhile n &lt; 5 {\n    println!(&quot;{}&quot;, n);\n    n += 1;\n}\n\n\/\/ loop \ubc18\ubcf5\ubb38\nloop { ... }    \/\/ while true { ... } \uacfc \uac19\uc74c<\/code><\/pre>\n<h2>6. \uc18c\uc720\uad8c\uacfc \ub300\uc5ec<\/h2>\n<h3>6.1 \uc18c\uc720\uad8c \uaddc\uce59<\/h3>\n<p>\ubcf5\uc0ac\ub294 Copy\/Clone \ud2b8\ub808\uc774\ud2b8 \ucc38\uc870<\/p>\n<pre><code class=\"language-rust\">let s1 = String::from(&quot;hello&quot;);\nlet s2 = s1;  \/\/ s1\uc758 \uc18c\uc720\uad8c\uc774 s2\ub85c \uc774\ub3d9\n\/\/ println!(&quot;{}&quot;, s1);  \/\/ \ucef4\ud30c\uc77c \uc5d0\ub7ec!<\/code><\/pre>\n<h3>6.2 \ucc38\uc870<\/h3>\n<p>\ucc38\uc870\ub294 \uc18c\uc720\uad8c \uc774\ub3d9\uc774 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<br \/>\n\uac00\ubcc0\ucc38\uc870\uc758 \uacbd\uc6b0 \uc5ed\ucc38\uc870<code>(*d)<\/code> \ub97c \ud574\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">    let a = 1;\n    let mut b = 2;\n\n    let c = &amp;a;\n    println!(&quot;{}&quot;, a);\n    println!(&quot;{}&quot;, c);\n\n    let d = &amp;mut b;\n    *d = 3;\n    println!(&quot;{}&quot;, b);<\/code><\/pre>\n<h2>7. \uad6c\uc870\uccb4<\/h2>\n<h3>7.1 \uad6c\uc870\uccb4\uc758 \uc885\ub958<\/h3>\n<pre><code class=\"language-rust\">\/\/ C \uc2a4\ud0c0\uc77c \uad6c\uc870\uccb4\nstruct Point {\n    x: f32,\n    y: f32,\n}\n\n\/\/ \uc720\ub2db \uad6c\uc870\uccb4\nstruct Unit;\n\n\/\/ \ud29c\ud50c \uad6c\uc870\uccb4\nstruct Pair(i32, f32);\n\nlet pair = Pair(1, 0.1);\nprintln!(&quot;pair contains {:?} and {:?}&quot;, pair.0, pair.1);<\/code><\/pre>\n<pre><code class=\"language-rust\">struct User {\n    username: String,\n    email: String,\n    active: bool,\n}\n\nlet user = User {\n    username: String::from(&quot;rust_user&quot;),\n    email: String::from(&quot;user@example.com&quot;),\n    active: true,\n};<\/code><\/pre>\n<h3>7.2 \uc720\ub2db \uad6c\uc870\uccb4<\/h3>\n<pre><code class=\"language-rust\">struct Logger;\n\ntrait Logging {\n    fn log(&amp;self, message: &amp;str);\n}\n\nimpl Logging for Logger {\n    fn log(&amp;self, message: &amp;str) {\n        println!(&quot;Log: {}&quot;, message);\n    }\n}\n\nlet logger = Logger;\nlogger.log(&quot;\ud14c\uc2a4\ud2b8 \uba54\uc2dc\uc9c0&quot;);<\/code><\/pre>\n<h3>7.3 \uad6c\uc870\uccb4 \uba54\uc18c\ub4dc<\/h3>\n<pre><code class=\"language-rust\">struct Rectangle {\n    width: u32,\n    height: u32,\n}\n\nimpl Rectangle {\n    \/\/ \uc778\uc2a4\ud134\uc2a4 \uba54\uc18c\ub4dc - &amp;self\ub97c \uccab \ubc88\uc9f8 \ub9e4\uac1c\ubcc0\uc218\ub85c \ubc1b\uc74c\n    fn area(&amp;self) -&gt; u32 {\n        self.width * self.height\n    }\n\n    \/\/ \uc5f0\uad00 \ud568\uc218(Associated Function) - self\ub97c \ub9e4\uac1c\ubcc0\uc218\ub85c \ubc1b\uc9c0 \uc54a\uc74c\n    \/\/ \uc8fc\ub85c \uc0dd\uc131\uc790\ub85c \uc0ac\uc6a9\ub428 (\uc608: String::from())\n    fn new(width: u32, height: u32) -&gt; Rectangle {\n        Rectangle { width, height }\n    }\n}\n\nfn main() {\n    \/\/ \uc5f0\uad00 \ud568\uc218 \ud638\ucd9c\n    let rect = Rectangle::new(30, 50);\n\n    \/\/ \uba54\uc18c\ub4dc \ud638\ucd9c\n    println!(&quot;\uc0ac\uac01\ud615\uc758 \ub113\uc774: {}&quot;, rect.area());\n}<\/code><\/pre>\n<h3>7.4 \ub77c\uc774\ud504\ud0c0\uc784 \ud30c\ub77c\ubbf8\ud130<\/h3>\n<p>\ub77c\uc774\ud504\ud0c0\uc784 \ud30c\ub77c\ubbf8\ud130 <code>&#039;a<\/code> \ub294 \uad6c\uc870\uccb4\uac00 \uc720\ud6a8\ud55c \ub3d9\uc548<br \/>\n\ucc38\uc870\ud615\uc774 \ubc14\ub77c\ubcf4\ub294 \uac12\uc758 \uc720\ud6a8\uc131\uc744 \ubcf4\uc7a5\ud569\ub2c8\ub2e4.<br \/>\n\ucef4\ud30c\uc77c \uc2dc\uc810\uc5d0 \uc720\ud6a8\uc131\uc744 \uccb4\ud06c\ud574\uc11c,<br \/>\n\uc624\ub958\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uae30 \uc704\ud55c \uac83\uc73c\ub85c,<br \/>\n\uc0dd\uba85\uc8fc\uae30\ub97c \ubcc0\uacbd\ud558\uac70\ub098 \ud558\ub294 \uac83\uc740 \uc544\ub2d9\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">struct User&lt;&#039;a&gt; {\n    username: &amp;&#039;a String,\n    email: &amp;&#039;a String,\n    active: bool,\n}\n\nlet username = String::from(&quot;rust_user&quot;);\nlet email = String::from(&quot;user@example.com&quot;);\n\nlet user = User {\n    username: &amp;username,\n    email: &amp;email,\n    active: true,\n};<\/code><\/pre>\n<h2>8. \uc5f4\uac70\ud615\uacfc \ud328\ud134 \ub9e4\uce6d<\/h2>\n<pre><code class=\"language-rust\">\/\/ 1. Option \uc5f4\uac70\ud615\nenum Option&lt;T&gt; {\n   Some(T),\n   None,\n}\n\nlet some_number = Some(5);\nmatch some_number {\n   Some(n) =&gt; println!(&quot;\uc22b\uc790: {}&quot;, n),\n   None =&gt; println!(&quot;\uac12\uc774 \uc5c6\uc74c&quot;),\n}\n\n\/\/ 2. \ub2e4\ub978 \ud0c0\uc785\uc744 \ud3ec\ud568\ud558\ub294 \uc5f4\uac70\ud615\nenum Shape {\n   Circle(f64),             \/\/ \ubc18\uc9c0\ub984\n   Rectangle(f64, f64),     \/\/ \uac00\ub85c, \uc138\ub85c\n   Triangle{a: f64, b: f64} \/\/ \ubc11\ubcc0, \ub192\uc774\n}\n\nlet shape = Shape::Rectangle(10.0, 20.0);\nmatch shape {\n   Shape::Circle(r) =&gt; println!(&quot;\uc6d0: \ubc18\uc9c0\ub984 = {}&quot;, r),\n   Shape::Rectangle(w, h) =&gt; println!(&quot;\uc0ac\uac01\ud615: {}x{}&quot;, w, h),\n   Shape::Triangle{a, b} =&gt; println!(&quot;\uc0bc\uac01\ud615: \ubc11\ubcc0={}, \ub192\uc774={}&quot;, a, b),\n}\n\n\/\/ 3. impl\ub85c \uba54\uc11c\ub4dc \uad6c\ud604\nimpl Shape {\n   fn area(&amp;self) -&gt; f64 {\n       match self {\n           Shape::Circle(r) =&gt; std::f64::consts::PI * r * r,\n           Shape::Rectangle(w, h) =&gt; w * h,\n           Shape::Triangle{a, b} =&gt; a * b \/ 2.0,\n       }\n   }\n}<\/code><\/pre>\n<h2>9. \uc5d0\ub7ec \ucc98\ub9ac<\/h2>\n<pre><code class=\"language-rust\">use std::fs::File;\n\nfn main() {\n    let file_result = File::open(&quot;hello.txt&quot;);\n\n    match file_result {\n        Ok(file) =&gt; println!(&quot;\ud30c\uc77c \uc5f4\uae30 \uc131\uacf5&quot;),\n        Err(error) =&gt; println!(&quot;\uc5d0\ub7ec: {}&quot;, error),\n    }\n}<\/code><\/pre>\n<h2>10. \ud2b8\ub808\uc774\ud2b8<\/h2>\n<p>\ud2b8\ub808\uc774\ud2b8\ub294 \ub2e4\ub978 \uc5b8\uc5b4\uc758 \uc778\ud130\ud398\uc774\uc2a4\uc640 \uc720\uc0ac\ud569\ub2c8\ub2e4.<\/p>\n<h3>10.1 \uc8fc\uc694 \ud2b8\ub808\uc774\ud2b8<\/h3>\n<h4>Copy\uc640 Clone<\/h4>\n<pre><code class=\"language-rust\">\/\/ Copy\ub294 \uac12\uc758 \ube44\ud2b8 \ub2e8\uc704 \ubcf5\uc0ac\ub97c \uc218\ud589\n#[derive(Copy, Clone)]\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nlet p1 = Point { x: 1, y: 2 };\nlet p2 = p1;\nprintln!(&quot;{}, {}&quot;, p1.x, p1.y);\nprintln!(&quot;{}, {}&quot;, p2.x, p2.y);\n\n\/\/ String \uc740 Copy \uc0ac\uc6a9\ubd88\uac00\n#[derive(Clone)]\nstruct User {\n    username: String,\n    email: String,\n    active: bool,\n}\n\nlet u1 = User { username: String::from(&quot;someone&quot;), email: String::from(&quot;&lt;EMAIL&gt;&quot;), active: true};\nlet u2 = u1.clone();\nprintln!(&quot;{}, {}, {}&quot;, u1.username, u1.email, u1.active);\nprintln!(&quot;{}, {}, {}&quot;, u2.username, u2.email, u2.active);\n\n\/\/ Copy \ub97c \uad6c\ud604\ud558\uc9c0 \uc54a\uc558\uc73c\ubbc0\ub85c \uc18c\uc720\uad8c\uc774 \uc774\ub3d9\ud569\ub2c8\ub2e4.\nlet u3 = u1;\nprintln!(&quot;{}, {}, {}&quot;, u3.username, u3.email, u3.active);\n\/\/ println!(&quot;{}, {}, {}&quot;, u1.username, u1.email, u1.active); \/\/ \ucef4\ud30c\uc77c\ub7ec \uc624\ub958<\/code><\/pre>\n<h4>Display\uc640 Debug<\/h4>\n<pre><code class=\"language-rust\">#[derive(Debug)]\nstruct Rectangle {\n    width: u32,\n    height: u32,\n}\n\nlet rectangle = Rectangle { width: 30, height: 50 };\n\n\/\/ Debug \ucd9c\ub825\nprintln!(&quot;{:?}&quot;, rectangle);\n\/\/ Rectangle { width: 30, height: 50 }\nprintln!(&quot;{:#?}&quot;, rectangle);\n\/\/ Rectangle {\n\/\/     width: 30,\n\/\/     height: 50,\n\/\/ }\n\n\/\/ Display \uad6c\ud604\nimpl std::fmt::Display for Rectangle {\n    fn fmt(&amp;self, f: &amp;mut std::fmt::Formatter) -&gt; std::fmt::Result {\n        write!(f, &quot;{}x{}&quot;, self.width, self.height)\n    }\n}\n\n\/\/ Display \ucd9c\ub825\nprintln!(&quot;{}&quot;, rectangle);\n\/\/ 30x50<\/code><\/pre>\n<h4>From\uacfc Into<\/h4>\n<p>\uba85\uc2dc\uc801 \uce90\uc2a4\ud305(casting) \uc744 \uc791\uc131\ud569\ub2c8\ub2e4.<br \/>\n\uc554\uc2dc\uc801 \uce90\uc2a4\ud305(Into) \ub294 \uc790\ub3d9\uc0dd\uc131\ub429\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">struct User {\n    username: String,\n    email: String,\n    active: bool,\n}\n\nstruct UserWithAge {\n    username: String,\n    email: String,\n    age: i32,\n    active: bool,\n}\n\nimpl From&lt;User&gt; for UserWithAge {\n   fn from(user: User) -&gt; Self {\n       UserWithAge {\n           username: user.username,\n           email: user.email,\n           active: user.active,\n           age: 0, \/\/ Default age value\n       }\n   }\n}\n\nimpl From&lt;UserWithAge&gt; for User {\n   fn from(user: UserWithAge) -&gt; Self {\n       User {\n           username: user.username,\n           email: user.email,\n           active: user.active,\n       }\n   }\n}\n\nlet user = User {\n    username: &quot;john&quot;.to_string(),\n    email: &quot;john@example.com&quot;.to_string(),\n    active: true,\n};\n\n\/\/ From \uc0ac\uc6a9\nlet user_with_age: UserWithAge = UserWithAge::from(user);\n\n\/\/ Into \uc0ac\uc6a9 \nlet user: User = user_with_age.into();<\/code><\/pre>\n<h4>TryFrom\uacfc TryInto<\/h4>\n<p>From\uacfc Into\uc640 \uc720\uc0ac\ud558\uc9c0\ub9cc \ubcc0\ud658\uc774 \uc2e4\ud328\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub429\ub2c8\ub2e4.<br \/>\nResult \ud0c0\uc785\uc744 \ubc18\ud658\ud558\uc5ec \uc2e4\ud328 \uac00\ub2a5\uc131\uc744 \uba85\uc2dc\uc801\uc73c\ub85c \ucc98\ub9ac\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">use std::convert::TryFrom;\n\nstruct NonNegativeNumber(i32);\n\nimpl TryFrom&lt;i32&gt; for NonNegativeNumber {\n    type Error = String;\n\n    fn try_from(value: i32) -&gt; Result&lt;Self, Self::Error&gt; {\n        if value &gt;= 0 {\n            Ok(NonNegativeNumber(value))\n        } else {\n            Err(&quot;\uc74c\uc218\ub294 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.&quot;.to_string())\n        }\n    }\n}\n\nimpl TryInto&lt;i32&gt; for NonNegativeNumber {\n    type Error = String;\n\n    fn try_into(self) -&gt; Result&lt;i32, Self::Error&gt; {\n        Ok(self.0)\n    }\n}\n\n\/\/ TryFrom \uc0ac\uc6a9\nlet positive = NonNegativeNumber::try_from(42);\nlet negative = NonNegativeNumber::try_from(-42);\n\nmatch positive {\n    Ok(value) =&gt; {\n        println!(&quot;success: {}&quot;, value.0);\n        \/\/ TryInto \ud0c0\uc785\uc744 \uba85\uc2dc\uc801\uc73c\ub85c \uc9c0\uc815\n        let val: Result&lt;i32, String&gt; = value.try_into();\n        match val {\n            Ok(v) =&gt; println!(&quot;original value: {}&quot;, v),\n            Err(e) =&gt; println!(&quot;conversion failed: {}&quot;, e)\n        }\n    }\n    Err(e) =&gt; {\n        println!(&quot;failed: {}&quot;, e);\n    }\n}\n\nmatch negative {\n    Ok(value) =&gt; {\n        println!(&quot;success: {}&quot;, value.0);\n    }\n    Err(e) =&gt; {\n        println!(&quot;failed: {}&quot;, e);\n    }\n}<\/code><\/pre>\n<h4>Default<\/h4>\n<p>\uc22b\uc790\ud615\uc758 \ub514\ud3f4\ud2b8\uac12\uc740 0 \ub610\ub294 0.0 \uc785\ub2c8\ub2e4.<br \/>\nString \uc758 \ub514\ud3f4\ud2b8\uac12\uc740 &quot;&quot; \uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">#[derive(Default)]\nstruct Settings {\n    timeout: u32,\n    port: u16,\n}\n\nlet settings = Settings::default();<\/code><\/pre>\n<h4>PartialEq\uc640 Eq<\/h4>\n<p>PartialEq \ub294 <code>==<\/code>, <code>!=<\/code> \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9 \uac00\ub2a5\ud558\uac8c \ud574\uc90d\ub2c8\ub2e4.<br \/>\nEq \ub294 \uc644\uc804 \ub3d9\ub4f1\uc131(\ubc18\uc0ac\uc131, \ub300\uce6d\uc131, \ucd94\uc774\uc131)\uc774 \ubcf4\uc7a5\ub420 \ub54c \uc0ac\uc6a9\ub429\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">\/\/ PartialEq\uc640 Eq\ub97c derive\ud558\uc5ec \uad6c\uc870\uccb4\uc758 \ub3d9\ub4f1\uc131 \ube44\uad50\uac00 \uac00\ub2a5\ud558\uac8c \ub429\ub2c8\ub2e4\n#[derive(PartialEq, Eq)]\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let p1 = Point { x: 1, y: 2 };\n    let p2 = Point { x: 1, y: 2 };\n    let p3 = Point { x: 3, y: 4 };\n\n    \/\/ == \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\uad50 \uac00\ub2a5\n    println!(&quot;p1 == p2: {}&quot;, p1 == p2);  \/\/ true\n    println!(&quot;p1 == p3: {}&quot;, p1 == p3);  \/\/ false\n\n    \/\/ != \uc5f0\uc0b0\uc790\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\n    println!(&quot;p1 != p3: {}&quot;, p1 != p3);  \/\/ true\n\n    \/\/ Vec \ub4f1\uc758 \uceec\ub809\uc158\uc5d0\uc11c contains \uba54\uc11c\ub4dc \uc0ac\uc6a9 \uac00\ub2a5\n    let points = vec![p1, p3];\n    println!(&quot;Contains p2: {}&quot;, points.contains(&amp;p2));  \/\/ true (p2\ub294 p1\uacfc \uac19\uc73c\ubbc0\ub85c)\n}\n\n\/\/ \uc5f4\uac70\ud615(enum)\uc5d0\ub3c4 \uc801\uc6a9 \uac00\ub2a5\n#[derive(PartialEq, Eq)]\nenum Status {\n    Active,\n    Inactive,\n    Pending,\n}\n\nfn check_status() {\n    let status1 = Status::Active;\n    let status2 = Status::Active;\n    let status3 = Status::Pending;\n\n    println!(&quot;status1 == status2: {}&quot;, status1 == status2);  \/\/ true\n    println!(&quot;status1 == status3: {}&quot;, status1 == status3);  \/\/ false\n}<\/code><\/pre>\n<p>\ubd80\ub3d9\uc18c\uc218\uc810 \ud0c0\uc785(f32, f64)\uc740 NaN \ub54c\ubb38\uc5d0 Eq\ub97c \uad6c\ud604\ud558\uc9c0 \uc54a\uc73c\uba70,<br \/>\nPartialEq\ub9cc \uad6c\ud604\ud569\ub2c8\ub2e4:<\/p>\n<pre><code class=\"language-rust\">let x = f64::NAN;\nassert!(x != x); \/\/ true - NaN\uc740 \uc790\uae30 \uc790\uc2e0\uacfc\ub3c4 \uac19\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4<\/code><\/pre>\n<h4>Drop<\/h4>\n<pre><code class=\"language-rust\">struct Resource {\n    data: String,\n}\n\nimpl Drop for Resource {\n    fn drop(&amp;mut self) {\n        \/\/ Resource \uac00 \uba54\ubaa8\ub9ac \ud574\uc81c\ub420 \ub54c \ud638\ucd9c\ub428\n        println!(&quot;\ub9ac\uc18c\uc2a4 \ud574\uc81c: {}&quot;, self.data);\n    }\n}<\/code><\/pre>\n<h3>10.2 \ud2b8\ub808\uc774\ud2b8 \uad6c\ud604<\/h3>\n<pre><code class=\"language-rust\">trait Summary {\n    fn summarize(&amp;self) -&gt; String;\n}\n\nstruct NewsArticle {\n    headline: String,\n    content: String,\n}\n\nimpl Summary for NewsArticle {\n    fn summarize(&amp;self) -&gt; String {\n        format!(&quot;{}: {}&quot;, self.headline, self.content)\n    }\n}\n\nlet article = NewsArticle {\n    headline: String::from(&quot;Newspaper headline&quot;),\n    content: String::from(&quot;Newspaper content&quot;),\n};\n\nprintln!(&quot;1 new article was created: {}&quot;, article.summarize());<\/code><\/pre>\n<h3>10.3 \ud2b8\ub808\uc774\ud2b8 \ubc14\uc6b4\ub4dc<\/h3>\n<h4>\uae30\ubcf8 \ud2b8\ub808\uc774\ud2b8 \ubc14\uc6b4\ub4dc<\/h4>\n<pre><code class=\"language-rust\">\/\/ T\ub294 Display\uc640 Clone \ud2b8\ub808\uc774\ud2b8\ub97c \uad6c\ud604\ud574\uc57c \ud568\nfn print_and_clone&lt;T: Display + Clone&gt;(t: T) {\n    println!(&quot;{}&quot;, t);\n    let _cloned = t.clone();\n}<\/code><\/pre>\n<h4>where \uc808\uc744 \uc0ac\uc6a9\ud55c \ud2b8\ub808\uc774\ud2b8 \ubc14\uc6b4\ub4dc<\/h4>\n<pre><code class=\"language-rust\">fn complex_function&lt;T, U&gt;(t: T, u: U) -&gt; i32 \nwhere \n    T: Display + Clone,\n    U: Clone + Debug,\n{\n    println!(&quot;{}&quot;, t);\n    println!(&quot;{:?}&quot;, u);\n    42\n}<\/code><\/pre>\n<h3>10.4 \ud2b8\ub808\uc774\ud2b8 \uac1d\uccb4 \ub3d9\uc801 \ub514\uc2a4\ud328\uce58<\/h3>\n<pre><code class=\"language-rust\">trait Draw {\n    fn draw(&amp;self);\n}\n\nstruct Button {\n    label: String,\n}\n\nimpl Draw for Button {\n    fn draw(&amp;self) {\n        println!(&quot;\uadf8\ub9ac\uae30: {}&quot;, self.label);\n    }\n}\n\n\/\/ \ud2b8\ub808\uc774\ud2b8 \uac1d\uccb4\ub97c \uc0ac\uc6a9\ud55c \ub3d9\uc801 \ub514\uc2a4\ud328\uce58\n\/\/ Draw \ud2b8\ub808\uc774\ud2b8\ub97c \uad6c\ud604\ud55c \ubaa8\ub4e0 \ud0c0\uc785\uc744 \ubc1b\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\/\/ \ucef4\ud30c\uc77c \ud0c0\uc784\uc5d0 \ud615\uc774 \ud655\uc815\ub418\uc9c0 \uc54a\uc73c\ubbc0\ub85c `dyn` \uc744 \ubd99\uc5ec\uc8fc\uc5b4\uc57c \ud569\ub2c8\ub2e4.\nfn draw_ui(ui_element: &amp;dyn Draw) {\n    ui_element.draw();\n}\n\nlet button = Button {label: &quot;button&quot;.to_string()};\ndraw_ui(&amp;button);<\/code><\/pre>\n<h3>10.5 \uc81c\ub124\ub9ad \ud2b8\ub808\uc774\ud2b8 \ubc14\uc6b4\ub4dc<\/h3>\n<pre><code class=\"language-rust\">use std::ops::Add;\n\n\/\/ \ucef4\ud30c\uc77c\ub7ec \uc624\ub958\n\/\/ + \uc5f0\uc0b0\uc790\ub294 Add \ud2b8\ub808\uc774\ud2b8\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc5b4\uc57c \ud558\ub294\ub370\n\/\/ \uc81c\ub124\ub9ad\uc744 \uc801\uc6a9\ud558\uba74 Add \ud2b8\ub808\uc774\ud2b8\uac00 \uad6c\ud604\ub418\uc9c0 \uc54a\ub294 \uacbd\uc6b0\ub3c4 \uc788\uc5b4\n\/\/ \ucef4\ud30c\uc77c\ub7ec \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4.\n\/\/ fn sum&lt;T&gt;(a: T, b: T) -&gt; T {\n\/\/     a + b\n\/\/ }\n\n\/\/ Add \ud2b8\ub808\uc774\ud2b8\uac00 \uad6c\ud604\ub41c \ud0c0\uc785\ub9cc \ubc1b\ub3c4\ub85d \uc81c\ud55c\nfn sum&lt;T: Add&lt;Output = T&gt;&gt;(a: T, b: T) -&gt; T {\n    a + b\n}\n\n\/\/ \uc0ac\uc6a9 \uc608\uc2dc\nlet int_sum = sum(5, 10);\nlet float_sum = sum(3.14, 2.86);\n\nimpl Add for Point {\n    type Output = Point;\n\n    fn add(self, rhs: Self) -&gt; Self::Output {\n        Point {\n            x: self.x + rhs.x,\n            y: self.y + rhs.y,\n        }\n    }\n}\n\nlet point_sum = sum(Point { x: 1, y: 2 }, Point { x: 3, y: 4 });<\/code><\/pre>\n<h2>11. \ud074\ub85c\uc800<\/h2>\n<h3>11.1 \uae30\ubcf8 \ubb38\ubc95<\/h3>\n<pre><code class=\"language-rust\">\/\/ \uae30\ubcf8 \ud074\ub85c\uc800 (\ud0c0\uc785 \ucd94\ub860)\n\/\/ \ucef4\ud30c\uc77c \uc2dc\uc810\uc5d0 \ud0c0\uc785\uc774 \ud655\uc815\ub418\ubbc0\ub85c \uc81c\ub124\ub9ad\uc774 \uc544\ub2d8.\nlet add = |x, y| x + y;\nlet result = add(5, 3);\nlet result2 = add(5.0, 3.0);  \/\/ \ucef4\ud30c\uc77c \uc624\ub958!\n\n\/\/ \ud0c0\uc785 \uba85\uc2dc\nlet multiply: fn(i32, i32) -&gt; i32 = |x, y| x * y;<\/code><\/pre>\n<h3>11.2 \ud074\ub85c\uc800 \ucea1\ucc98<\/h3>\n<p>\uc8fc\ubcc0 \ubcc0\uc218\ub97c \ud074\ub85c\uc800 \ub0b4\ubd80\ub85c \ucea1\uccd0\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">let mut list = vec![1, 2, 3];\nlet mut borrows = || list.push(4);\nprintln!(&quot;{:?}&quot;, &amp;list);\n\n\/\/ move \ud0a4\uc6cc\ub4dc\ub85c \uc18c\uc720\uad8c \uc774\uc804\nlet list = vec![1, 2, 3];\nlet owns = move || println!(&quot;\uc18c\uc720: {:?}&quot;, list);<\/code><\/pre>\n<h3>11.3 \ud074\ub85c\uc800 \ud2b8\ub808\uc774\ud2b8 (\ucea1\uccd0 \uad6c\ud604\ubc29\uc2dd)<\/h3>\n<p>Fn\/FnMut\/FnOnce \ub294 \ucef4\ud30c\uc77c\ub7ec\uc5d0 \uc758\ud574 \uc790\ub3d9\uc73c\ub85c \uacb0\uc815\ub428<\/p>\n<pre><code class=\"language-rust\">\/\/ Fn - \ubd88\ubcc0 \ucc38\uc870\ub85c \ucea1\ucc98 (\uac12\uc744 \ubcc0\uacbd\uc2dc\ud0a4\uc9c0 \uc54a\uc74c)\nlet text = String::from(&quot;Hello&quot;);\nlet print = || println!(&quot;{}&quot;, text);\n\n\/\/ FnMut - \uac00\ubcc0 \ucc38\uc870\ub85c \ucea1\ucc98 (\uac12\uc744 \ubcc0\uacbd)\nlet mut counter = 0;\nlet mut increment = || {\n    counter += 1;\n    println!(&quot;{}&quot;, counter);\n};\n\n\/\/ FnOnce - \uc18c\uc720\uad8c \ud68d\ub4dd\nlet text = String::from(&quot;Hello&quot;);\nlet consume = move || {\n    println!(&quot;{}&quot;, text);\n    \/\/ \uac12\uc744 \ud574\uc81c\n};\n\n\/\/ move \ub97c \uba85\uc2dc\ud558\uc9c0 \uc54a\uc544\ub3c4 FnOnce \uc73c\ub85c \uc791\ub3d9\nlet mut list = vec![1, 2, 3];\nlet mut borrows = || drop(list);  \/\/ drop\uc740 \uc18c\uc720\uad8c\uc744 \ud544\uc694\ub85c \ud568\nborrows();<\/code><\/pre>\n<h3>11.4 Iterator\uc640 \ud074\ub85c\uc800<\/h3>\n<p>.iter() \ub294 \uc5b8\uc81c\ub098 \uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \ubcc0\uacbd\uc2dc\ud0a4\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">let numbers = vec![1, 2, 3, 4, 5];\n\n\/\/ map\nlet doubled: Vec&lt;_&gt; = numbers.iter().map(|x| x * 2).collect();\n\/\/ doubled = [2, 4, 6, 8, 10]\n\n\/\/ filter\nlet evens: Vec&lt;_&gt; = numbers.iter().filter(|x| *x % 2 == 0).collect();\n\/\/ evens = [2, 4]\n\n\/\/ fold\nlet sum = numbers.iter()\n              .fold(0,    \/\/ \ucd08\uae30\uac12 0\uc73c\ub85c \uc2dc\uc791\n              |acc, x|    \/\/ acc: \ub204\uc801\uac12, x: \ud604\uc7ac \uc694\uc18c\n              acc + x);\n\/\/ sum = 15\n\n\/\/ chain\nlet more_numbers = vec![6, 7, 8];\nlet combined: Vec&lt;_&gt; = numbers.iter()\n    .chain(more_numbers.iter())\n    .collect();\n\/\/ combined = [1, 2, 3, 4, 5, 6, 7, 8]<\/code><\/pre>\n<pre><code class=\"language-rust\">\/\/ .iter_mut() : \uac00\ubcc0 \ucc38\uc870(mutable reference)\nlet mut numbers = vec![1, 2, 3];\nnumbers.iter_mut().for_each(|x| *x *= 2);\n\/\/ numbers = [2, 4, 6]\n\n\/\/ .into_iter() : \uc18c\uc720\uad8c \uc774\ub3d9\nlet numbers = vec![1, 2, 3];\nlet doubled: Vec&lt;_&gt; = numbers.into_iter().map(|x| x * 2).collect();\n\/\/ numbers\ub294 \uc774\uc81c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4<\/code><\/pre>\n<h3>11.5 \uace0\ucc28 \ud568\uc218<\/h3>\n<pre><code class=\"language-rust\">fn apply&lt;F&gt;(f: F, x: i32) -&gt; i32 \nwhere \n    F: Fn(i32) -&gt; i32 \n{\n    f(x)\n}\n\nlet double = |x| x * 2;\nlet result = apply(double, 5);\n\n\/\/ \ud074\ub85c\uc800 \ubc18\ud658\nfn create_adder(n: i32) -&gt; impl Fn(i32) -&gt; i32 {\n    move |x| x + n\n}\n\nlet add_five = create_adder(5);\nlet result = add_five(10); \/\/ 15<\/code><\/pre>\n<h2>12. \ubaa8\ub4c8\uacfc \ud328\ud0a4\uc9c0 \uc2dc\uc2a4\ud15c<\/h2>\n<h3>12.1 \ubaa8\ub4c8 \uae30\ubcf8<\/h3>\n<pre><code class=\"language-rust\">\/\/ lib.rs\nmod front_of_house {\n    pub mod hosting {\n        pub fn add_to_waitlist() {}\n        fn seat_at_table() {}\n    }\n}\n\nuse crate::front_of_house::hosting;\n\npub fn eat_at_restaurant() {\n    hosting::add_to_waitlist();\n}\n\n\/\/ main.rs\nuse RustTest::eat_at_restaurant;\n\nfn main() {\n    eat_at_restaurant();\n}<\/code><\/pre>\n<h3>12.2 \ud30c\uc77c \uc2dc\uc2a4\ud15c \uae30\ubc18 \ubaa8\ub4c8<\/h3>\n<pre><code class=\"language-plaintext\">my_project\/\n\u251c\u2500\u2500 Cargo.toml\n\u2514\u2500\u2500 src\/\n    \u251c\u2500\u2500 main.rs\n    \u251c\u2500\u2500 lib.rs\n    \u2514\u2500\u2500 models\/\n        \u251c\u2500\u2500 mod.rs\n        \u251c\u2500\u2500 user.rs\n        \u2514\u2500\u2500 order.rs<\/code><\/pre>\n<pre><code class=\"language-rust\">\/\/ models\/mod.rs\npub mod user;\npub mod order;\n\n\/\/ models\/user.rs\npub struct User {\n    pub name: String,\n    pub age: u32,\n}\n\n\/\/ main.rs\nuse crate::models::user::User;<\/code><\/pre>\n<h3>12.3 \uac00\uc2dc\uc131\uacfc \ud504\ub77c\uc774\ubc84\uc2dc<\/h3>\n<pre><code class=\"language-rust\">mod back_of_house {\n    #[derive(Debug)]\n    pub struct Breakfast {\n        pub (crate) toast: String,                  \/\/ \ud504\ub85c\uc81d\ud2b8 \ud55c\uc815 public\n        seasonal_fruit: String,                     \/\/ private \ud544\ub4dc\n    }\n\n    impl Breakfast {\n        pub fn summer(toast: &amp;str) -&gt; Breakfast {   \/\/ \uc804\uccb4 public\n            Breakfast {\n                toast: String::from(toast),\n                seasonal_fruit: String::from(&quot;\ubcf5\uc22d\uc544&quot;),\n            }\n        }\n    }\n}\n\nuse back_of_house::Breakfast;\n\nfn main() {\n    let breakfast = Breakfast::summer(&quot;toast&quot;);\n    println!(&quot;{:#?}&quot;, &amp;breakfast);;\n}<\/code><\/pre>\n<h3>12.4 use \ud0a4\uc6cc\ub4dc<\/h3>\n<pre><code class=\"language-rust\">use std::collections::HashMap;\n\n\/\/ use std::io;\n\/\/ use std::io::Write;\nuse std::io::{self, Write};\n\n\/\/ \ub2e4\uc2dc \ub0b4\ubcf4\ub0b4\uae30\npub use crate::front_of_house::hosting;\n\n\/\/ as \ud0a4\uc6cc\ub4dc\ub85c \uc774\ub984 \ubcc0\uacbd\nuse std::io::Error as IoError;\n\n\/\/ glob \uc5f0\uc0b0\uc790 (\ubaa8\ub4e0 \uacf5\uac1c \ud56d\ubaa9 \uac00\uc838\uc624\uae30)\nuse std::collections::*;<\/code><\/pre>\n<h3>12.5 \ud328\ud0a4\uc9c0\uc640 Cargo.toml<\/h3>\n<pre><code class=\"language-toml\">[package]\nname = &quot;my_project&quot;\nversion = &quot;0.1.0&quot;\nedition = &quot;2021&quot;\n\n[dependencies]\nserde = { version = &quot;1.0&quot;, features = [&quot;derive&quot;] }\ntokio = &quot;1.0&quot;\n\n[dev-dependencies]\npretty_assertions = &quot;1.0&quot;\n\n[workspace]\nmembers = [\n    &quot;core&quot;,\n    &quot;cli&quot;,\n    &quot;web&quot;,\n]<\/code><\/pre>\n<h3>12.6 \uc791\uc5c5\uacf5\uac04(Workspace)<\/h3>\n<pre><code class=\"language-plaintext\">workspace\/\n\u251c\u2500\u2500 Cargo.toml\n\u251c\u2500\u2500 core\/\n\u2502   \u251c\u2500\u2500 Cargo.toml\n\u2502   \u2514\u2500\u2500 src\/\n\u251c\u2500\u2500 cli\/\n\u2502   \u251c\u2500\u2500 Cargo.toml\n\u2502   \u2514\u2500\u2500 src\/\n\u2514\u2500\u2500 web\/\n    \u251c\u2500\u2500 Cargo.toml\n    \u2514\u2500\u2500 src\/<\/code><\/pre>\n<h3>12.7 \uc678\ubd80 \ud06c\ub808\uc774\ud2b8 \uc0ac\uc6a9<\/h3>\n<pre><code class=\"language-rust\">\/\/ Cargo.toml\uc5d0 \uc758\uc874\uc131 \ucd94\uac00 \ud6c4\nuse serde::{Serialize, Deserialize};\n\n#[derive(Serialize, Deserialize)]\nstruct Point {\n    x: i32,\n    y: i32,\n}<\/code><\/pre>\n<h2>13. \uc2a4\ub9c8\ud2b8 \ud3ec\uc778\ud130<\/h2>\n<ul>\n<li>\n<p>\ud799 \uba54\ubaa8\ub9ac\uc5d0 \ud560\ub2f9<\/p>\n<p>\ub300\uc6a9\ub7c9 \ub370\uc774\ud130\uc5d0 \ub300\ud574 \uba54\ubaa8\ub9ac \ud560\ub2f9\uc774 \uac00\ub2a5\ud574\uc9d1\ub2c8\ub2e4.<br \/>\n\uba54\ubaa8\ub9ac \ud574\uc81c\uac00 \uc790\ub3d9\uc73c\ub85c \uc774\ub8e8\uc5b4\uc9d1\ub2c8\ub2e4.<\/p>\n<\/li>\n<li>\n<p>\uc7ac\uadc0\uc801 \ub370\uc774\ud130 \uad6c\uc870 \uc9c0\uc6d0<\/p>\n<p>\ub370\uc774\ud0c0\uc758 \ud06c\uae30\uac00 \ucef4\ud30c\uc77c \uc2dc\uc810\uc5d0 \uace0\uc815\ub420 \uc218 \uc5c6\ub294 \uc7ac\uadc0\uc801\uc778 \ub370\uc774\ud0c0 \uad6c\uc870\ub97c \uc9c0\uc6d0\ud569\ub2c8\ub2e4.<\/p>\n<\/li>\n<li>\n<p>Deref \ud2b8\ub808\uc774\ud2b8 \uad6c\ud604<\/p>\n<p>\uc5ed\ucc38\uc870\ub97c \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub429\ub2c8\ub2e4.<\/p>\n<ul>\n<li>\uc790\ub3d9 \uc5ed\ucc38\uc870\ub294 \uba54\uc18c\ub4dc \ud638\ucd9c \ub610\ub294 \uc801\uc808\ud55c \ud2b8\ub808\uc774\ud2b8\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc744\ub54c \ud638\ucd9c\ub428<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\uba54\ubaa8\ub9ac \ub204\uc218 \ubc29\uc9c0<\/p>\n<p>\uba54\ubaa8\ub9ac \ub204\uc218 \uac19\uc740 \ubb38\uc81c\ub97c \ucef4\ud30c\uc77c \uc2dc\uc810\uc5d0 \ubc29\uc9c0\ud569\ub2c8\ub2e4.<\/p>\n<\/li>\n<\/ul>\n<h3>13.1 <code>Box&lt;T&gt;<\/code><\/h3>\n<pre><code class=\"language-rust\">#[derive(Debug)]\nstruct Person {\n    name: String,\n    age: u8,\n    email: String,\n}\n\nfn main() {\n    \/\/ \ud799\uc5d0 Person \uad6c\uc870\uccb4 \ud560\ub2f9\n    let person = Box::new(Person {\n        name: String::from(&quot;Alice&quot;),\n        age: 30,\n        email: String::from(&quot;alice@example.com&quot;),\n    });\n\n    \/\/ \ud560\ub2f9\ub41c \ub370\uc774\ud130 \ucd9c\ub825\n    println!(&quot;Person: {:?}&quot;, person);\n\n    \/\/ \uad6c\uc870\uccb4 \ud544\ub4dc \uc811\uadfc\n    println!(&quot;Name: {}&quot;, person.name);\n    println!(&quot;Age: {}&quot;, person.age);\n    println!(&quot;Email: {}&quot;, person.email);\n\n    \/\/ Box\ub97c \ud1b5\ud574 \uc18c\uc720\uad8c \uc774\ub3d9\n    let moved_person = person; \/\/ person\uc758 \uc18c\uc720\uad8c\uc774 moved_person\uc73c\ub85c \uc774\ub3d9\n    println!(&quot;Moved Person: {:?}&quot;, moved_person);\n\n    \/\/ person\uc740 \ub354 \uc774\uc0c1 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc74c (\uc18c\uc720\uad8c \uc774\ub3d9\uc73c\ub85c \uc778\ud574)\n    \/\/ println!(&quot;{:?}&quot;, person); \/\/ \ucef4\ud30c\uc77c \uc5d0\ub7ec \ubc1c\uc0dd\n}<\/code><\/pre>\n<h3>13.2 <code>Rc&lt;T&gt;<\/code> (Reference Counting)<\/h3>\n<p>\ub3d9\uc77c\ud55c \ub370\uc774\ud0c0\ub97c \ucc38\uc870\ud569\ub2c8\ub2e4.<br \/>\n\uae30\ubcf8\uc801\uc73c\ub85c \ub370\uc774\ud0c0 \uc218\uc815\uc774 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4.<\/p>\n<p>\ub370\uc774\ud0c0\ub97c \uc218\uc815\ud558\ub824\uba74 <code>Rc&lt;RefCell&lt;Vec&lt;i32&gt;&gt;&gt;<\/code> \uc640 \uac19\uc774 <code>RefCell<\/code> \ub97c \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">use std::rc::Rc;\n\n\/\/ \uc5ec\ub7ec \uc18c\uc720\uc790\nlet data = Rc::new(vec![1, 2, 3]);\nlet data2 = Rc::clone(&amp;data);\nlet data3 = Rc::clone(&amp;data);\n\nprintln!(&quot;\ucc38\uc870 \uce74\uc6b4\ud2b8: {}&quot;, Rc::strong_count(&amp;data));\n\n\/\/ \uc21c\ud658 \ucc38\uc870 \ubc29\uc9c0\nstruct Node {\n    next: Option&lt;Rc&lt;RefCell&lt;Node&gt;&gt;&gt;,\n    value: i32,\n}\n\nlet node1 = Rc::new(RefCell::new(Node { next: None, value: 1 }));\nlet node2 = Rc::new(RefCell::new(Node { next: Some(Rc::clone(&amp;node1)), value: 2 }));\nnode1.borrow_mut().next = Some(Rc::clone(&amp;node2)); \/\/ \uc21c\ud658 \ucc38\uc870 \ubc1c\uc0dd\n\n\/\/ \uc21c\ud658 \ucc38\uc870 \ud574\uacb0\uc740 \uc544\ub798\uc5d0\uc11c \uc124\uba85 (Weak)<\/code><\/pre>\n<h3>13.3 <code>RefCell&lt;T&gt;<\/code><\/h3>\n<p><code>borrow_mut()<\/code> \ub97c \uc774\uc6a9\ud574 \uac00\ubcc0 \ucc38\uc870\ub97c \uac00\uc838\uc62c \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">use std::cell::RefCell;\n\n\/\/ \ub0b4\ubd80 \uac00\ubcc0\uc131\nlet data = RefCell::new(5);\n\n\/\/ \ub7f0\ud0c0\uc784 borrowing \uaddc\uce59 \uccb4\ud06c\nlet mut mut_ref = data.borrow_mut();\n*mut_ref += 1;\ndrop(mut_ref);  \/\/ \uba85\uc2dc\uc801 \ubc18\ud658\n\nlet ref_one = data.borrow();\nprintln!(&quot;\ub370\uc774\ud130: {}&quot;, *ref_one);<\/code><\/pre>\n<h3>13.4 <code>Arc&lt;T&gt;<\/code> (Atomic Reference Counting)<\/h3>\n<p>Arc\ub294 \uc5ec\ub7ec \uc2a4\ub808\ub4dc\uac00 \ub3d9\uc77c\ud55c \ub370\uc774\ud130\ub97c \uc18c\uc720\ud558\uace0 \uacf5\uc720\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc90d\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">use std::sync::Arc;\nuse std::thread;\n\n\/\/ \uc2a4\ub808\ub4dc \uac04 \uacf5\uc720\nlet data = Arc::new(vec![1, 2, 3, 4]);\nlet mut handles = vec![];\n\nfor i in 0..3 {\n    let data_clone = Arc::clone(&amp;data);\n    handles.push(thread::spawn(move || {\n        \/\/ Arc \uac12\uc758 \uc18c\uc720\uad8c\uc744 \uc774\ub3d9\uc2dc\ud0b5\ub2c8\ub2e4.\n        println!(&quot;\uc2a4\ub808\ub4dc {}: {:?}&quot;, i, *data_clone);\n        i\n    }));\n}\n\nfor handle in handles {\n    \/\/ handle.join() \uc740 \uc2a4\ub808\ub4dc\uac00 \uc885\ub8cc\ud558\uae30\ub97c \uae30\ub2e4\ub9bd\ub2c8\ub2e4.\n    let result = handle.join();\n    match result {\n        Ok(result) =&gt; println!(&quot;\uc2a4\ub808\ub4dc {} \uc885\ub8cc&quot;, result),\n        Err(e) =&gt; println!(&quot;{:?}&quot;, e),\n    }\n}<\/code><\/pre>\n<h3>13.5 <code>Mutex&lt;T&gt;<\/code>\uc640 <code>Arc&lt;T&gt;<\/code> \uc870\ud569<\/h3>\n<p>Mutex\ub294 \ud55c \ubc88\uc5d0 \ud558\ub098\uc758 \uc2a4\ub808\ub4dc\ub9cc \ub370\uc774\ud130\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub3c4\ub85d \ubcf4\uc7a5\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-rust\">use std::sync::{Arc, Mutex};\nuse std::thread;\n\nfn main() {\n    let counter = Arc::new(Mutex::new(0));\n    let mut handles = vec![];\n\n    for _ in 0..10 {\n        let counter = Arc::clone(&amp;counter);\n        let handle = thread::spawn(move || {\n            match counter.lock() {\n                Ok(mut num) =&gt; {\n                    *num += 1;\n                }\n                Err(poisoned) =&gt; {\n                    \/\/ \ub2e4\ub978 \uc2a4\ub808\ub4dc\uac00 \uac12\uc744 \uc7a0\uadfc \uc0c1\ud0dc\uc5d0\uc11c \ud328\ub2c9\uc774 \ubc1c\uc0dd\ud55c \uacbd\uc6b0\n                    eprintln!(&quot;\ubba4\ud14d\uc2a4\uac00 \ub3c5\ud654\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ubcf5\uad6c\ub97c \uc2dc\ub3c4\ud569\ub2c8\ub2e4.&quot;);\n                    let mut num = poisoned.into_inner();\n                    *num += 1; \/\/ \ub3c5\ud654\ub41c \ubba4\ud14d\uc2a4\ub97c \ubcf5\uad6c\ud55c \ud6c4 \uac12\uc744 \uc99d\uac00\uc2dc\ud0b4\n                }\n            }\n        });\n        handles.push(handle);\n    }\n\n    for handle in handles {\n        if let Err(e) = handle.join() {\n            eprintln!(&quot;\uc2a4\ub808\ub4dc\uac00 \ud328\ub2c9\uc744 \ubc1c\uc0dd\uc2dc\ucf30\uc2b5\ub2c8\ub2e4: {:?}&quot;, e);\n        }\n    }\n\n    match counter.lock() {\n        Ok(num) =&gt; println!(&quot;Result: {}&quot;, *num),\n        Err(poisoned) =&gt; {\n            let num = poisoned.into_inner();\n            println!(&quot;Result: {}&quot;, *num);\n        }\n    };\n}<\/code><\/pre>\n<h3>13.6 <code>Weak&lt;T&gt;<\/code><\/h3>\n<pre><code class=\"language-rust\">use std::rc::{Rc, Weak};\nuse std::cell::RefCell;\n\n\/\/ \uc21c\ud658 \ucc38\uc870 \ud574\uacb0\nstruct Node {\n    next: Option&lt;Rc&lt;RefCell&lt;Node&gt;&gt;&gt;,\n    parent: RefCell&lt;Weak&lt;RefCell&lt;Node&gt;&gt;&gt;,\n    value: i32,\n}\n\nimpl Node {\n    fn new(value: i32) -&gt; Rc&lt;RefCell&lt;Self&gt;&gt; {\n        Rc::new(RefCell::new(Node {\n            next: None,\n            parent: RefCell::new(Weak::new()),\n            value,\n        }))\n    }\n}\n\n\/\/ \uc0ac\uc6a9 \uc608\uc2dc\nlet leaf = Node::new(3);\nlet branch = Node::new(5);\nleaf.borrow_mut().parent = RefCell::new(Rc::downgrade(&amp;branch));\nbranch.borrow_mut().next = Some(Rc::clone(&amp;leaf));<\/code><\/pre>\n<h3>13.7 Custom Smart Pointer<\/h3>\n<pre><code class=\"language-rust\">struct CustomSmartPointer&lt;T&gt; {\n    data: T,\n}\n\nimpl&lt;T&gt; Drop for CustomSmartPointer&lt;T&gt; {\n    fn drop(&amp;mut self) {\n        println!(&quot;CustomSmartPointer \uba54\ubaa8\ub9ac \ud574\uc81c!&quot;);\n    }\n}\n\nimpl&lt;T&gt; Deref for CustomSmartPointer&lt;T&gt; {\n    type Target = T;\n\n    fn deref(&amp;self) -&gt; &amp;Self::Target {\n        &amp;self.data\n    }\n}\n\n\/\/ \uc0ac\uc6a9\nlet c = CustomSmartPointer { data: String::from(&quot;\ub370\uc774\ud130&quot;) };\n\/\/ Display \ud2b8\ub808\uc774\ud2b8\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc544 \uc790\ub3d9 \uc5ed\ucc38\uc870 \ubd88\uac00\nprintln!(&quot;\ud3ec\uc778\ud130: {}&quot;, *c);<\/code><\/pre>\n<h2>14. \ube44\ub3d9\uae30 \ud504\ub85c\uadf8\ub798\ubc0d<\/h2>\n<h3>14.1 \uae30\ubcf8 \uac1c\ub150<\/h3>\n<pre><code class=\"language-rust\">use tokio;\n\n#[tokio::main]\nasync fn main() {\n    println!(&quot;\ube44\ub3d9\uae30 \uc2dc\uc791&quot;);\n    let result = do_something().await;\n    println!(&quot;result \uc218\uc2e0 \ud6c4 \uc2e4\ud589&quot;);\n    println!(&quot;\uacb0\uacfc: {}&quot;, result);\n    println!(&quot;result \uc218\uc2e0 \ud6c4 \uc2e4\ud589&quot;);\n}\n\nasync fn do_something() -&gt; String {\n    tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;\n    String::from(&quot;\uc644\ub8cc&quot;)\n}<\/code><\/pre>\n<h3>14.2 Future \ud2b8\ub808\uc774\ud2b8<\/h3>\n<pre><code class=\"language-rust\">let result = timer.await;<\/code><\/pre>\n<ul>\n<li>\n<p>await \ud0a4\uc6cc\ub4dc\ub97c \ub9cc\ub098\uba74 \ud604\uc7ac Future\uac00 \uc2e4\ud589\uae30(executor)\uc5d0 \ub4f1\ub85d\ub428<\/p>\n<\/li>\n<li>\n<p>\uc2e4\ud589\uae30\ub294 Future\ub97c \uc2e4\ud589 \ud050\uc5d0 \ucd94\uac00\ud558\uace0 \ud3f4\ub9c1\uc744 \uc2dc\uc791\ud569\ub2c8\ub2e4.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"language-rust\">use std::future::Future;\nuse std::pin::Pin;\nuse std::task::{Context, Poll};\n\nstruct MyFuture {\n    count: u32,\n}\n\nimpl Future for MyFuture {\n    type Output = u32;\n\n    fn poll(mut self: Pin&lt;&amp;mut Self&gt;, cx: &amp;mut Context&lt;&#039;_&gt;) -&gt; Poll&lt;Self::Output&gt; {\n        if self.count &gt;= 10 {\n            Poll::Ready(self.count)\n        } else {\n            cx.waker().wake_by_ref();\n            self.count += 1;\n            Poll::Pending\n        }\n    }\n}\n\n#[tokio::main]\nasync fn main() {\n    println!(&quot;Timer started!&quot;);\n    let timer = MyFuture { count: 0 };\n    let result = timer.await;\n    println!(&quot;Result: {}&quot;, result);\n}<\/code><\/pre>\n<h3>14.3 \ub3d9\uc2dc\uc131 \ucc98\ub9ac<\/h3>\n<pre><code class=\"language-rust\">use tokio;\n\n#[tokio::main]\nasync fn main() {\n    \/\/ \ubcd1\ub82c \uc791\uc5c5\n    let handles: Vec&lt;_&gt; = (0..3)\n        .map(|i| {\n            \/\/ tokio::spawn\n            \/\/ \ud0dc\uc2a4\ud06c\uac00 \uc989\uc2dc \uc0dd\uc131\ub418\uace0 \uc2e4\ud589 \ud050\uc5d0 \ub4e4\uc5b4\uac11\ub2c8\ub2e4 (\uc989\uc2dc \uc2e4\ud589)\n            tokio::spawn(async move {\n                tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;\n                println!(&quot;\uc791\uc5c5 {} \uc644\ub8cc&quot;, i);\n                i\n            })\n        })\n        .collect();\n\n    \/\/ \uacb0\uacfc \uc218\uc9d1\n    for handle in handles {\n        \/\/ \uc2e4\ud589\uacb0\uacfc \ub300\uae30\n        match handle.await {\n            Ok(result) =&gt; println!(&quot;\uacb0\uacfc: {}&quot;, result),\n            Err(e) =&gt; eprintln!(&quot;\uc791\uc5c5 \uc2e4\ud589 \uc911 \uc624\ub958 \ubc1c\uc0dd: {}&quot;, e),\n        }\n    }\n}<\/code><\/pre>\n<h3>14.4 Stream<\/h3>\n<pre><code class=\"language-rust\">use tokio;\nuse futures::stream::{self, StreamExt};\n\nasync fn process_stream() {\n    let mut stream = stream::iter(1..=5)\n        .map(|x| async move { x * 2 })\n        .buffer_unordered(2);             \/\/ \ucd5c\ub300 2\uac1c\uc758 \uc791\uc5c5\uc744 \ub3d9\uc2dc\uc5d0 \uc2e4\ud589\n\n    \/\/ \ud55c \ubc88\uc5d0 \ucd5c\ub300 2\uac1c\uc758 \uc791\uc5c5\ub9cc \ub3d9\uc2dc\uc5d0 \uc2e4\ud589 (stream.next().await)\n    while let Some(n) = stream.next().await {\n        println!(&quot;\uac12: {}&quot;, n);\n    }\n}\n\n#[tokio::main]\nasync fn main() {\n    process_stream().await;\n}<\/code><\/pre>\n<h3>14.5 Select\uc640 Join<\/h3>\n<pre><code class=\"language-rust\">use tokio::select;\n\nasync fn race_tasks() {\n    let t1 = some_async_task();\n    let t2 = another_async_task();\n\n    \/\/ \uc5ec\ub7ec \ube44\ub3d9\uae30 \uc791\uc5c5 \uc911 \uac00\uc7a5 \uba3c\uc800 \uc644\ub8cc\ub418\ub294 \uc791\uc5c5\uc744 \ucc98\ub9ac (select!)\n    \/\/ \ub450 \ubc88\uc9f8 \uc774\ud6c4\uc758 \uc791\uc5c5\uc740 \ucc98\ub9ac\uc548\ud568\n    select! {\n        val = t1 =&gt; println!(&quot;task 1 \uc644\ub8cc: {}&quot;, val),\n        val = t2 =&gt; println!(&quot;task 2 \uc644\ub8cc: {}&quot;, val),\n    }\n\n    \/\/ join\uc73c\ub85c \ubaa8\ub4e0 \uc791\uc5c5 \uc644\ub8cc \ub300\uae30\n    let (result1, result2) = tokio::join!(t1, t2);\n}<\/code><\/pre>\n<h3>14.6 \ucc44\ub110 \ud1b5\uc2e0<\/h3>\n<pre><code class=\"language-rust\">use tokio::sync::mpsc;\n\n#[tokio::main]\nasync fn main() {\n    \/\/ \ubc84\ud37c\uac00 \uac00\ub4dd \ucc3c\uc744 \ub54c \ube14\ub85c\ud0b9 (\uc804\uc1a1 \ub300\uae30)\n    let (tx, mut rx) = mpsc::channel(32);\n\n    \/\/ \uc1a1\uc2e0\uc790 \uc791\uc5c5\n    let sender = tokio::spawn(async move {\n        for i in 0..5 {\n            \/\/ \uc21c\ucc28\uc2e4\ud589\n            tx.send(i).await.unwrap();\n        }\n    });\n\n    \/\/ \uc218\uc2e0\uc790 \uc791\uc5c5\n    \/\/ \ucc44\ub110(mpsc)\uc758 \ud2b9\uc131\uc0c1 FIFO(First In First Out) \ubc29\uc2dd\uc73c\ub85c \ub3d9\uc791\n    while let Some(value) = rx.recv().await {\n        println!(&quot;\ubc1b\uc740 \uac12: {}&quot;, value);\n    }\n}<\/code><\/pre>\n<h3>14.7 \uc624\ub958 \ucc98\ub9ac<\/h3>\n<pre><code class=\"language-rust\">use std::io;\nuse tokio;\n\n#[tokio::main]\nasync fn main() -&gt; Result&lt;(), Box&lt;dyn std::error::Error&gt;&gt; {\n    match async_operation().await {\n        Ok(result) =&gt; println!(&quot;\uc131\uacf5: {}&quot;, result),\n        Err(e) =&gt; eprintln!(&quot;\uc5d0\ub7ec: {}&quot;, e),\n    }\n    Ok(())\n}\n\nasync fn async_operation() -&gt; io::Result&lt;String&gt; {\n    \/\/ \ube44\ub3d9\uae30 \uc791\uc5c5 \uc2dc\ubbac\ub808\uc774\uc158\n    tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;\n    Ok(String::from(&quot;\uc791\uc5c5 \uc644\ub8cc&quot;))\n}<\/code><\/pre>\n<h3>14.8 \ube44\ub3d9\uae30 \ub77d\uacfc \ub3d9\uae30\ud654<\/h3>\n<ul>\n<li>Mutex: \ud55c \ubc88\uc5d0 \ud558\ub098\uc758 \uc811\uadfc\ub9cc \ud5c8\uc6a9<\/li>\n<li>RwLock: \ub2e4\uc218\uc758 \ub3d9\uc2dc \uc77d\uae30 \ub610\ub294 \ub2e8\uc77c \uc4f0\uae30\ub97c \ud5c8\uc6a9<\/li>\n<\/ul>\n<pre><code class=\"language-rust\">use tokio::sync::{Mutex, RwLock};\n\n#[tokio::main]\nasync fn main() {\n    \/\/ \ube44\ub3d9\uae30 \ubba4\ud14d\uc2a4\n    let mutex = Arc::new(Mutex::new(0));\n\n    \/\/ \uc77d\uae30-\uc4f0\uae30 \ub77d\n    let rwlock = Arc::new(RwLock::new(String::new()));\n\n    \/\/ \ubba4\ud14d\uc2a4 \uc0ac\uc6a9\n    let mut lock = mutex.lock().await;\n    *lock += 1;\n    drop(lock);\n\n    \/\/ \uc77d\uae30-\uc4f0\uae30 \ub77d \uc0ac\uc6a9\n    \/\/ \uc4f0\uae30 \ub77d\uc774 \uac78\ub824\uc788\uc73c\uba74 \uc544\ubb34\ub3c4 \uc77d\uae30 \ubd88\uac00\n    let mut write = rwlock.write().await;\n    write.push_str(&quot;\ub370\uc774\ud130&quot;);\n    \/\/ \uc4f0\uae30 \ub77d \ud574\uc81c\n    drop(write);\n\n    let read = rwlock.read().await;\n    println!(&quot;\ub370\uc774\ud130: {}&quot;, *read);\n}<\/code><\/pre>\n<h2>15. \ub9e4\ud06c\ub85c \uc2dc\uc2a4\ud15c<\/h2>\n<h3>15.1 \uc120\uc5b8\uc801 \ub9e4\ud06c\ub85c (Declarative Macros)<\/h3>\n<pre><code class=\"language-rust\">\/\/ \uae30\ubcf8 \ub9e4\ud06c\ub85c \uc815\uc758\nmacro_rules! say_hello {\n    () =&gt; {\n        println!(&quot;Hello!&quot;);\n    };\n}\n\n\/\/ \ub9e4\uac1c\ubcc0\uc218\ub97c \ubc1b\ub294 \ub9e4\ud06c\ub85c\nmacro_rules! print_ex {\n    \/\/ $\ub294 \ub9e4\ud06c\ub85c \uc548\uc5d0\uc11c \ubcc0\uc218\ub97c \uc120\uc5b8\ud558\uac70\ub098 \uc0ac\uc6a9\ud560 \ub54c \ud544\uc694\ud55c \uc811\ub450\uc0ac\n    ($x:expr) =&gt; {\n        println!(&quot;{:?}&quot;, $x);\n    };\n}\n\n\/\/ \uc5ec\ub7ec \ud328\ud134 \ub9e4\uce6d\nmacro_rules! vec_strs {\n    \/\/ \ube48 \ubca1\ud130\n    () =&gt; {\n        Vec::new()\n    };\n    \/\/ ($(...),*) \uc758 \ud615\ud0dc\n    \/\/ \uc27c\ud45c\ub85c \uad6c\ubd84\ub41c \uad04\ud638\uc548\uc758\uac83(\ud45c\ud604\uc2dd) (0 \uac1c \uc774\uc0c1)\n    \/\/ ($($x:expr),+) =&gt; \ud55c\uac1c \uc774\uc0c1\n    ($($x:expr),*) =&gt; {\n        {\n            let mut temp_vec = Vec::new();\n            $(\n                temp_vec.push($x.to_string());\n            )*\n            temp_vec\n        }\n    };\n}\n\nsay_hello!();\nprint_ex!(10);\nprint_ex!(&quot;Hello&quot;);\nprint_ex!(vec_strs!(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;));<\/code><\/pre>\n<h3>15.2 \uc808\ucc28\uc801 \ub9e4\ud06c\ub85c (Procedural Macros)<\/h3>\n<p>\uc808\ucc28\uc801 \ub9e4\ud06c\ub85c \ud06c\ub808\uc774\ud2b8(\ud504\ub85c\uc81d\ud2b8)\ub294 \ubc18\ub4dc\uc2dc \ubcc4\ub3c4\uc758 \ud06c\ub808\uc774\ud2b8\uc5ec\uc57c \ud569\ub2c8\ub2e4.<br \/>\n(\uac19\uc740 \ud06c\ub808\uc774\ud2b8 \ub0b4\uc5d0\uc11c \uc815\uc758\ud560 \uc218 \uc5c6\uc74c)<\/p>\n<ul>\n<li>\ud30c\uc0dd \ub9e4\ud06c\ub85c: \uad6c\uc870\uccb4\ub098 \uc5f4\uac70\ud615\uc5d0 \ub300\ud55c \uad6c\ud604\uc744 \uc790\ub3d9\ud654\ud560 \ub54c \uc0ac\uc6a9<\/li>\n<li>\uc18d\uc131 \ub9e4\ud06c\ub85c: \ud568\uc218\ub098 \uad6c\uc870\uccb4\uc5d0 \uba54\ud0c0\ub370\uc774\ud130\ub098 \ucd94\uac00 \uae30\ub2a5\uc744 \ubd80\uc5ec\ud560 \ub54c \uc0ac\uc6a9<\/li>\n<li>\ud568\uc218\ud615 \ub9e4\ud06c\ub85c: \uc784\uc758\uc758 \ud1a0\ud070\uc744 \uc785\ub825\ubc1b\uc544 \uc0c8\ub85c\uc6b4 \ucf54\ub4dc\ub97c \uc0dd\uc131\ud560 \ub54c \uc0ac\uc6a9<\/li>\n<\/ul>\n<h4>\ud3f4\ub354 \ubc0f \ud30c\uc77c<\/h4>\n<p>\uae30\uc874 \ud504\ub85c\uc81d\ud2b8\uc5d0 \uc808\ucc28\uc801 \ub9e4\ud06c\ub85c\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574 \uc544\ub798\uc640 \uac19\uc774 \ud3f4\ub354 \ubc0f \ud30c\uc77c\uc744 \uc0dd\uc131\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-text\">my_project\/\n\u251c\u2500\u2500 Cargo.toml\n\u251c\u2500\u2500 src\/\n\u2502   \u2514\u2500\u2500 main.rs  (\ub610\ub294 lib.rs)\n\u2514\u2500\u2500 crates\/\n    \u2514\u2500\u2500 my_macro\/\n        \u251c\u2500\u2500 Cargo.toml\n        \u2514\u2500\u2500 src\/\n            \u2514\u2500\u2500 lib.rs<\/code><\/pre>\n<p>crates\/my_macro\/Cargo.toml<\/p>\n<pre><code class=\"language-toml\">[package]\nname = &quot;my_macro&quot;\nversion = &quot;0.1.0&quot;\nedition = &quot;2021&quot;\n\n[lib]\nproc-macro = true\n\n[dependencies]\nsyn = { version = &quot;2.0&quot;, features = [&quot;full&quot;] }\nquote = &quot;1.0&quot;\nproc-macro2 = &quot;1.0&quot;<\/code><\/pre>\n<p>crates\/my_macro\/src\/lib.rs<\/p>\n<pre><code class=\"language-rust\">extern crate proc_macro;\nuse proc_macro::TokenStream;\nuse quote::quote;\nuse syn;\nuse syn::{parse_macro_input, LitStr};\n\n\/\/ \ud30c\uc0dd \ub9e4\ud06c\ub85c (Derive Macros)\n#[proc_macro_derive(HelloWorld)]\npub fn hello_world_derive(input: TokenStream) -&gt; TokenStream {\n    let ast = syn::parse(input).unwrap();\n    impl_hello_world(&amp;ast)\n}\n\nfn impl_hello_world(ast: &amp;syn::DeriveInput) -&gt; TokenStream {\n    let name = &amp;ast.ident;\n    let gen = quote! {\n        impl #name {\n            fn hello_world() {\n                println!(&quot;Hello, World! I&#039;m {}&quot;, stringify!(#name));\n            }\n        }\n    };\n    gen.into()\n}\n\n\/\/ \uc18d\uc131 \ub9e4\ud06c\ub85c (Attribute Macros)\n#[proc_macro_attribute]\npub fn my_route(attr: TokenStream, item: TokenStream) -&gt; TokenStream {\n    \/\/ \uacbd\ub85c \ubb38\uc790\uc5f4\uc744 \ud30c\uc2f1\n    let path = parse_macro_input!(attr as LitStr).value();\n    let input = parse_macro_input!(item as syn::ItemFn);\n    let func_ident = &amp;input.sig.ident;\n\n    let expanded = quote! {\n        #[doc = #path]\n        #input\n    };\n\n    expanded.into()\n}\n\n\/\/ \ud568\uc218\ud615 \ub9e4\ud06c\ub85c (Function-like Macros)\n#[proc_macro]\npub fn sql(input: TokenStream) -&gt; TokenStream {\n    let input_str = input.to_string();\n\n    \/\/ SQL \ucffc\ub9ac\ub97c \ud30c\uc2f1\ud558\uace0 \uac80\uc99d\ud558\ub294 \ub85c\uc9c1\n    let output = format!(\n        r#&quot;\n        String::from(&quot;{}&quot;)\n        &quot;#,\n        input_str\n    );\n\n    output.parse().unwrap()\n}<\/code><\/pre>\n<pre><code class=\"language-rust\">#[derive(HelloWorld)]\nstruct MyStruct;\n\nfn main() {\n    MyStruct::hello_world();\n}<\/code><\/pre>\n<pre><code class=\"language-rust\">#[my_route(&quot;\/hello&quot;)]<\/code><\/pre>\n<pre><code class=\"language-rust\">sql!(SELECT * FROM users)<\/code><\/pre>\n<h4>\uae30\uc874 \ud504\ub85c\uc81d\ud2b8 \uc124\uc815<\/h4>\n<p>\ub8e8\ud2b8 Cargo.toml\uc5d0 workspace\uc640 \uc758\uc874\uc131\uc744 \ucd94\uac00\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-toml\">[dependencies]\nmy_macro = { path = &quot;crates\/my_macro&quot; }\n\n[workspace]\nmembers = [\n    &quot;crates\/my_macro&quot;\n]<\/code><\/pre>\n<h4>\ub8e8\ud2b8 \ud504\ub85c\uc81d\ud2b8<\/h4>\n<pre><code class=\"language-rust\">use my_macro::HelloWorld;\nuse my_macro::my_route;\nuse my_macro::sql;\n\n#[derive(HelloWorld)]\nstruct Greeter;\n\n\/\/ &quot;\/api\/users&quot; \ud638\ucd9c\uc2dc \uc0ac\uc6a9\ub428\n#[my_route(&quot;\/api\/users&quot;)]\nfn handle_users() {\n    \/\/ \ucc98\ub9ac \ub85c\uc9c1\n}\n\nfn main() {\n    Greeter::hello_world();\n\n    let query = sql!(SELECT * FROM users WHERE id = 1);\n    println!(&quot;Generated query: {}&quot;, query);\n}<\/code><\/pre>\n<h3>15.3 \ub9e4\ud06c\ub85c \uaddc\uce59\uacfc \uc9c0\uc815\uc790<\/h3>\n<pre><code class=\"language-rust\">macro_rules! match_type {\n    \/\/ 1. ($x:expr) =&gt; { ... };\n    \/\/ \ud45c\ud604\uc2dd(expression)\uc744 \ub9e4\uce6d\ud569\ub2c8\ub2e4.\n    \/\/ \uc608: 1 + 2, foo(), vec![1, 2, 3] \ub4f1\n\n    \/\/ 2. ($x:ident) =&gt; { ... };\n    \/\/ \uc2dd\ubcc4\uc790(identifier)\ub97c \ub9e4\uce6d\ud569\ub2c8\ub2e4.\n    \/\/ \uc608: foo, bar, my_variable \ub4f1\uc758 \ubcc0\uc218\uba85\uc774\ub098 \ud568\uc218\uba85\n\n    \/\/ 3. ($x:ty) =&gt; { ... };\n    \/\/ \ud0c0\uc785(type)\uc744 \ub9e4\uce6d\ud569\ub2c8\ub2e4.\n    \/\/ \uc608: i32, String, Vec&lt;T&gt; \ub4f1\n\n    \/\/ 4. ($x:path) =&gt; { ... };\n    \/\/ \uacbd\ub85c(path)\ub97c \ub9e4\uce6d\ud569\ub2c8\ub2e4.\n    \/\/ \uc608: std::vec::Vec, my_module::MyStruct \ub4f1\n\n    \/\/ 5. ($x:tt) =&gt; { ... };\n    \/\/ \ud1a0\ud070 \ud2b8\ub9ac(token tree)\ub97c \ub9e4\uce6d\ud569\ub2c8\ub2e4.\n    \/\/ \ub2e8\uc77c \ud1a0\ud070\uc774\ub098 \uad04\ud638\ub85c \ubb36\uc778 \ud1a0\ud070 \uc2dc\ud000\uc2a4\ub97c \ub9e4\uce6d\n    \/\/ \uc608: 1, (1 + 2), [1, 2, 3] \ub4f1\n\n    \/\/ 6. ($x:item) =&gt; { ... };\n    \/\/ \uc544\uc774\ud15c(item)\uc744 \ub9e4\uce6d\ud569\ub2c8\ub2e4.\n    \/\/ \uc608: \ud568\uc218 \uc815\uc758, \uad6c\uc870\uccb4 \uc815\uc758, \ubaa8\ub4c8 \ub4f1\n}<\/code><\/pre>\n<h3>15.4 \ub9e4\ud06c\ub85c \ubc18\ubcf5\uacfc \uc870\uac74<\/h3>\n<pre><code class=\"language-rust\">macro_rules! vector {\n    ( $( $x:expr ),* ) =&gt; {\n        {\n            let mut temp_vec = Vec::new();\n            $(\n                temp_vec.push($x);\n            )*\n            temp_vec\n        }\n    };\n}\n\n\/\/ \uc870\uac74\ubd80 \ub9e4\ud06c\ub85c\nmacro_rules! conditional {\n    ($x:expr, $y:expr, if $condition:expr) =&gt; {\n        if $condition {\n            $x\n        } else {\n            $y\n        }\n    };\n}<\/code><\/pre>\n<h3>15.5 \ub9e4\ud06c\ub85c \ub0b4\ubcf4\ub0b4\uae30\uc640 \uac00\uc838\uc624\uae30<\/h3>\n<pre><code class=\"language-rust\">\/\/ \ub9e4\ud06c\ub85c \ub0b4\ubcf4\ub0b4\uae30\n#[macro_export]\nmacro_rules! public_macro {\n    () =&gt; {\n        println!(&quot;\uacf5\uac1c \ub9e4\ud06c\ub85c&quot;);\n    };\n}\n\n\/\/ \ub9e4\ud06c\ub85c \uac00\uc838\uc624\uae30\nuse my_crate::public_macro;\n\/\/ \ub610\ub294\n#[macro_use]\nextern crate my_crate;<\/code><\/pre>\n<h3>15.6 \ub514\ubc84\uae45\uacfc \uc624\ub958 \ucc98\ub9ac<\/h3>\n<pre><code class=\"language-rust\">macro_rules! debug_print {\n    ($($arg:tt)*) =&gt; {{\n        #[cfg(debug_assertions)]\n        println!(&quot;\ub514\ubc84\uadf8: {}&quot;, format!($($arg)*));\n    }};\n}\n\n\/\/ \ub9e4\ud06c\ub85c \ud655\uc7a5 \ucd94\uc801\n#[rustc_macro_transparency = &quot;semitransparent&quot;]\nmacro_rules! trace_macro {\n    ($name:ident) =&gt; {\n        println!(&quot;\ub9e4\ud06c\ub85c {} \uc2e4\ud589&quot;, stringify!($name));\n    };\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Rust \uae30\ucd08 \uac15\uc88c \ub7ec\uc2a4\ud2b8\uc758 \ubaa8\ub4e0 \ubb38\ubc95\uc744 \uc124\uba85\ud558\uba74 \ub108\ubb34 \uae38\uc5b4\uc9c0\ubbc0\ub85c, \uac00\uc7a5 \uae30\ucd08\uc801\uc778 \ub0b4\uc6a9\ub9cc \uc791\uc131\ud569\ub2c8\ub2e4. 1. \uc2dc\uc791\ud558\uae30 1.1 Hello World fn main() { println!(&quot;Hello World!&quot;); } \uccab \ubc88\uc9f8 Rust \ud504\ub85c\uadf8\ub7a8\uc785\ub2c8\ub2e4. main \ud568\uc218\ub294 \ud504\ub85c\uadf8\ub7a8\uc758 \uc9c4\uc785\uc810\uc774\uba70, println! \ub9e4\ud06c\ub85c\ub97c \uc0ac\uc6a9\ud574 \ud14d\uc2a4\ud2b8\ub97c \ucd9c\ub825\ud569\ub2c8\ub2e4. 1.2 \uc8fc\uc11d \/\/ \ud55c \uc904 \uc8fc\uc11d \/* \uc5ec\ub7ec \uc904 \uc8fc\uc11d *\/ 1.3 \uc11c\uc2dd\ud654\ub41c \ucd9c\ub825 println!(&quot;{} \ub354\ud558\uae30 {} \uc740\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=9772\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[42],"tags":[],"class_list":["post-9772","post","type-post","status-publish","format-standard","hentry","category-rust-language"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/9772","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9772"}],"version-history":[{"count":99,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/9772\/revisions"}],"predecessor-version":[{"id":9880,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/9772\/revisions\/9880"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=9772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=9772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}