<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>조용한 담장</title>
    <link>https://iosroid.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 17 May 2026 01:41:08 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>iosroid</managingEditor>
    <item>
      <title>Rust Using Structs to Structure Related Data - Quick Reference</title>
      <link>https://iosroid.tistory.com/137</link>
      <description>&lt;h1&gt;5. Using Structs to Structure Related Data&lt;/h1&gt;
&lt;p&gt;이 글은 &lt;a href=&quot;https://doc.rust-lang.org/book/ch05-00-structs.html&quot;&gt;Rust 공식 문서 5장(Using Structs to Structure Related Data)&lt;/a&gt;의 내용을 기반으로 빠르게 훑어볼 수 있도록 정리한 요약본입니다.&lt;/p&gt;
&lt;h2&gt;5.1. Defining and Instantiating Structs&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch05-01-defining-structs.html&quot;&gt;https://doc.rust-lang.org/book/ch05-01-defining-structs.html&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;핵심 개념 및 코드 스니핏&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;정의 (Definition):&lt;/strong&gt; &lt;code&gt;struct&lt;/code&gt; 키워드로 필드와 타입을 묶음.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;struct User {
    username: String,
    email: String,
    active: bool,
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;인스턴스화 (Instantiation):&lt;/strong&gt; 정의된 키에 값을 할당 (순서 무관).&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;let user1 = User {
    email: String::from(&amp;quot;someone@example.com&amp;quot;),
    username: String::from(&amp;quot;someusername123&amp;quot;),
    active: true,
};&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;가변성 (Mutability):&lt;/strong&gt; 인스턴스 전체가 &lt;code&gt;mut&lt;/code&gt;여야 필드 변경 가능.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;let mut user1 = User { /* ... */ };
user1.email = String::from(&amp;quot;another@example.com&amp;quot;); // 가능
// let user2 = User { ... }; user2.email = ...; // 불가능 (컴파일 에러)&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;strong&gt;필드 초기화 축약 (Field Init Shorthand):&lt;/strong&gt; 변수명과 필드명이 같으면 생략.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;fn build(email: String, username: String) -&amp;gt; User {
    User {
        email,    // email: email 과 동일
        username, // username: username 과 동일
        active: true,
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;&lt;strong&gt;구조체 갱신 문법 (Struct Update Syntax):&lt;/strong&gt; &lt;code&gt;..instance&lt;/code&gt;로 나머지 필드 복사.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;// user1의 active 등을 가져오고 email만 새로 설정
let user2 = User {
    email: String::from(&amp;quot;new@example.com&amp;quot;),
    ..user1 
};
// 주의: String 같은 힙 데이터 필드가 user1에서 user2로 이동(Move)되면 user1은 재사용 불가&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;&lt;strong&gt;튜플 구조체 (Tuple Structs):&lt;/strong&gt; 필드명 없는 구조체.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;struct Color(i32, i32, i32);
let black = Color(0, 0, 0);
// black.0 으로 접근&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;&lt;strong&gt;유닛 구조체 (Unit-Like Structs):&lt;/strong&gt; 필드가 없는 구조체 (트레이트 구현용).&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;struct AlwaysEqual;
let subject = AlwaysEqual;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;통합 실전 예제&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;struct User {
    active: bool,
    username: String,
    email: String,
}

struct Color(i32, i32, i32); // 튜플 구조체
struct AlwaysEqual;          // 유닛 구조체

fn main() {
    // 1. 가변 인스턴스 생성
    let mut user1 = User {
        email: String::from(&amp;quot;someone@example.com&amp;quot;),
        username: String::from(&amp;quot;someusername123&amp;quot;),
        active: true,
    };

    // 2. 필드 값 변경
    user1.email = String::from(&amp;quot;another@example.com&amp;quot;);

    // 3. 구조체 갱신 문법 (Struct Update Syntax)
    // user1의 username(String) 소유권이 user2로 이동(Move)됨에 주의!
    let user2 = User {
        email: String::from(&amp;quot;user2@example.com&amp;quot;),
        ..user1 
    };

    println!(&amp;quot;User2 Email: {}&amp;quot;, user2.email);
    println!(&amp;quot;User2 Username: {}&amp;quot;, user2.username); 
    // println!(&amp;quot;{}&amp;quot;, user1.username); // 컴파일 에러! (소유권 이동됨)
    println!(&amp;quot;User1 Active: {}&amp;quot;, user1.active); // Copy 타입(bool)은 여전히 사용 가능

    // 4. 튜플 구조체 사용
    let black = Color(0, 0, 0);
    println!(&amp;quot;Black Color R: {}, G: {}, B: {}&amp;quot;, black.0, black.1, black.2);

    // 5. 유닛 구조체 사용
    let _subject = AlwaysEqual;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=57bbc6cc8fce9fa1eb73b66abad13328&quot;&gt;5.1 Defining and Instantiating Structs - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://gist.github.com/rust-play/57bbc6cc8fce9fa1eb73b66abad13328&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5.2. An Example Program Using Structs&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch05-02-example-structs.html&quot;&gt;https://doc.rust-lang.org/book/ch05-02-example-structs.html&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;핵심 개념 및 코드 스니핏&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;의미 부여 (Semantic Grouping):&lt;/strong&gt; 개별 변수보다 구조체가 데이터의 관계를 명확히 함.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;// Bad: fn area(width: u32, height: u32) -&amp;gt; u32
// Good:
struct Rectangle { width: u32, height: u32 }
fn area(rect: &amp;amp;Rectangle) -&amp;gt; u32 { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Debug&lt;/code&gt; 트레이트 파생 (Derive Debug):&lt;/strong&gt; 구조체 출력을 위해 &lt;code&gt;#[derive(Debug)]&lt;/code&gt; 추가.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;#[derive(Debug)]
struct Rectangle { width: u32, height: u32 }&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;포맷팅 출력:&lt;/strong&gt; &lt;code&gt;{:?}&lt;/code&gt; 또는 &lt;code&gt;{:#?}&lt;/code&gt; 사용.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;let rect = Rectangle { width: 30, height: 50 };
println!(&amp;quot;rect: {:?}&amp;quot;, rect);   // 한 줄 출력
println!(&amp;quot;rect: {:#?}&amp;quot;, rect);  // 들여쓰기 출력 (Pretty Print)&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;dbg!&lt;/code&gt; 매크로:&lt;/strong&gt; 디버깅 정보를 stderr로 출력하고 값을 반환.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;let width = dbg!(30 * 2); // 60을 출력하고 변수에 할당
dbg!(&amp;amp;rect); // 파일명, 라인번호, 값 출력
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;통합 실전 예제&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;#[derive(Debug)] // 구조체를 출력 가능하게 만듦
struct Rectangle {
    width: u32,
    height: u32,
}

fn area(rectangle: &amp;amp;Rectangle) -&amp;gt; u32 {
    rectangle.width * rectangle.height
}

fn main() {
    let scale = 2;
    let rect1 = Rectangle {
        // dbg!는 값을 반환하므로 필드 할당 식 중간에 사용 가능
        width: dbg!(30 * scale), 
        height: 50,
    };

    println!(
        &amp;quot;The area of the rectangle is {} square pixels.&amp;quot;,
        area(&amp;amp;rect1)
    );

    // {:?} : 기본적인 Debug 출력
    println!(&amp;quot;rect1 is {:?}&amp;quot;, rect1);

    // {:#?} : 읽기 편한 Debug 출력
    println!(&amp;quot;rect1 is {:#?}&amp;quot;, rect1);

    // dbg! 매크로 활용 (소유권을 뺏기지 않으려 참조를 넘김)
    dbg!(&amp;amp;rect1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=a8be48801b0c590d55d3a5abd6e9f458&quot;&gt;5.2 An Example Program Using Structs - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://gist.github.com/rust-play/a8be48801b0c590d55d3a5abd6e9f458&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5.3. Methods&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch05-03-method-syntax.html&quot;&gt;https://doc.rust-lang.org/book/ch05-03-method-syntax.html&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;핵심 개념 및 코드 스니핏&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;메서드 정의 (&lt;code&gt;impl&lt;/code&gt; block):&lt;/strong&gt; 함수가 아닌 구조체 컨텍스트 내의 메서드.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;impl Rectangle {
    fn area(&amp;amp;self) -&amp;gt; u32 { /* ... */ }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;self&lt;/code&gt; 파라미터의 종류:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;self&lt;/code&gt;: 읽기 전용 (가장 많이 사용).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;mut self&lt;/code&gt;: 인스턴스 내부 값 변경 시 사용.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;self&lt;/code&gt;: 소유권을 가져감 (메서드 종료 시 인스턴스 해제됨).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;impl Rectangle {
    fn read(&amp;amp;self) {}       // 읽기
    fn change(&amp;amp;mut self) {} // 쓰기
    fn consume(self) {}     // 소유권 가져오기
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;연관 함수 (Associated Functions):&lt;/strong&gt; &lt;code&gt;self&lt;/code&gt;가 없는 함수. 주로 생성자(&lt;code&gt;::new&lt;/code&gt;)로 사용.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;impl Rectangle {
    fn square(size: u32) -&amp;gt; Self { // Self는 Rectangle의 별칭
        Self { width: size, height: size }
    }
}
// 호출: Rectangle::square(10);&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;strong&gt;다중 &lt;code&gt;impl&lt;/code&gt; 블록:&lt;/strong&gt; 코드를 분리하여 작성 가능.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;impl Rectangle { fn area(&amp;amp;self) ... }
impl Rectangle { fn can_hold(&amp;amp;self) ... }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;통합 실전 예제&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // 1. 메서드: &amp;amp;self (Immutable Borrow)
    fn area(&amp;amp;self) -&amp;gt; u32 {
        self.width * self.height
    }

    // 2. 메서드: 다른 인스턴스와 상호작용
    fn can_hold(&amp;amp;self, other: &amp;amp;Rectangle) -&amp;gt; bool {
        self.width &amp;gt; other.width &amp;amp;&amp;amp; self.height &amp;gt; other.height
    }

    // 3. 메서드: 필드명과 동일한 이름 (Getter)
    fn width(&amp;amp;self) -&amp;gt; bool {
        self.width &amp;gt; 0
    }

    // 4. 메서드: &amp;amp;mut self (Mutable Borrow) - 상태 변경
    fn resize(&amp;amp;mut self, factor: u32) {
        self.width *= factor;
        self.height *= factor;
    }
}

// 별도의 impl 블록 (조직화를 위해 분리 가능)
impl Rectangle {
    // 5. 연관 함수: self가 없음 (생성자 역할)
    // 호출 시 :: 연산자 사용
    fn square(size: u32) -&amp;gt; Self {
        Self {
            width: size,
            height: size,
        }
    }
}

fn main() {
    let mut rect1 = Rectangle { width: 30, height: 50 };
    let rect2 = Rectangle { width: 10, height: 40 };
    let rect3 = Rectangle { width: 60, height: 45 };

    // 연관 함수 호출 (::)
    let sq = Rectangle::square(20); 

    println!(&amp;quot;Area of rect1: {}&amp;quot;, rect1.area()); // 자동 참조/역참조 기능으로 (&amp;amp;rect1).area()와 동일

    // 메서드와 필드 이름이 같을 경우, 괄호() 유무로 구분
    if rect1.width() {
        println!(&amp;quot;Rect1 width exists: {}&amp;quot;, rect1.width);
    }

    println!(&amp;quot;Can rect1 hold rect2? {}&amp;quot;, rect1.can_hold(&amp;amp;rect2));
    println!(&amp;quot;Can rect1 hold rect3? {}&amp;quot;, rect1.can_hold(&amp;amp;rect3));

    // 상태 변경 메서드 호출
    rect1.resize(2);
    println!(&amp;quot;Resized rect1: {:#?}&amp;quot;, rect1);

    println!(&amp;quot;Square constructed: {:?}&amp;quot;, sq);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=7ed9df64d05736e534f4d47b44e8e7bf&quot;&gt;5.3 Methods - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://gist.github.com/rust-play/7ed9df64d05736e534f4d47b44e8e7bf&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;</description>
      <category>Rust</category>
      <category>rust</category>
      <category>struct</category>
      <category>러스트</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/137</guid>
      <comments>https://iosroid.tistory.com/137#entry137comment</comments>
      <pubDate>Fri, 2 Jan 2026 12:23:21 +0900</pubDate>
    </item>
    <item>
      <title>Rust Understanding Ownership - Quick Reference</title>
      <link>https://iosroid.tistory.com/136</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 &lt;a href=&quot;https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Rust 공식 문서 4장(Understanding&amp;nbsp;Ownership)&lt;/a&gt;의 내용을 기반으로 빠르게 훑어볼 수 있도록 정리한 요약본입니다.&lt;/p&gt;
&lt;h1&gt;4. Understanding Ownership&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rust가 가비지 컬렉터 없이 메모리 안전성을 보장하는 핵심 메커니즘입니다.&lt;br /&gt;&lt;b&gt;&quot;누가 메모리를 해제할 책임이 있는가?&quot;&lt;/b&gt;를 결정하는 규칙들의 집합입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.1. What Is Ownership?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;The 3 Rules&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Rust의 각각의 값은 해당 값의 &lt;b&gt;Owner(소유자)&lt;/b&gt;라고 불리는 변수가 있다.&lt;/li&gt;
&lt;li&gt;한 번에 딱 &lt;b&gt;하나의 Owner&lt;/b&gt;만 존재할 수 있다.&lt;/li&gt;
&lt;li&gt;Owner가 스코프 밖으로 벗어나면, 값은 버려진다(&lt;b&gt;Dropped&lt;/b&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메모리 동작: Move vs Copy&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 타입이 힙(Heap)을 쓰느냐 스택(Stack)을 쓰느냐에 따라 대입 연산의 동작이 다릅니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Case 1: Move (힙 데이터 - String 등)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;힙에 저장되는 데이터는 변수 대입 시 &lt;b&gt;얕은 복사(포인터 복사)&lt;/b&gt;가 일어나며, &lt;b&gt;기존 변수는 무효화&lt;/b&gt;됩니다. 이를 &lt;b&gt;Move&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;#[test]
fn test_ownership_move() {
    let s1 = String::from(&quot;hello&quot;);
    let s2 = s1; // 소유권이 s2로 이동(Move)됨.

    // println!(&quot;{}, world!&quot;, s1); // 컴파일 에러! s1은 이제 유효하지 않음 (Use of moved value)
    println!(&quot;{}, world!&quot;, s2); // 정상 작동
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Case 2: Copy (스택 데이터 - 정수, 불리언 등)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크기가 고정된 스택 데이터는 &lt;code&gt;Copy&lt;/code&gt; 트레이트가 구현되어 있어, 대입 시 값이 &lt;b&gt;자동 복사&lt;/b&gt;됩니다. 기존 변수도 계속 사용 가능합니다.&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;#[test]
fn test_stack_copy() {
    let x = 5;
    let y = x; // x의 값이 복사되어 y에 할당됨.

    println!(&quot;x = {}, y = {}&quot;, x, y); // 둘 다 사용 가능
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Case 3: Clone (깊은 복사)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;힙 데이터를 그대로 유지하면서 새로 하나 더 만들고 싶다면 &lt;code&gt;.clone()&lt;/code&gt;을 명시적으로 호출해야 합니다.&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;#[test]
fn test_deep_copy() {
    let s1 = String::from(&quot;hello&quot;);
    let s2 = s1.clone(); // 힙 메모리 데이터까지 완전히 복사 (비용 발생)

    println!(&quot;s1 = {}, s2 = {}&quot;, s1, s2); // 둘 다 사용 가능
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Quick Tip:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수에 값을 전달할 때도 &lt;code&gt;Move&lt;/code&gt;가 발생합니다. 값을 함수에 넘겨주고 다시 쓰고 싶다면 반환값으로 돌려받거나, 아래의 '참조(Reference)'를 써야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=13a9002a223a71ca81f5013f6b30b495&quot;&gt;4.1. What Is Ownership? - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gist.github.com/rust-play/13a9002a223a71ca81f5013f6b30b495&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.2 References and Borrowing&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소유권을 넘기지(Move) 않고 값에 접근하고 싶을 때 사용합니다. &lt;code&gt;&amp;amp;&lt;/code&gt; 기호를 사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참조의 규칙 (The Rules of References)&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;어느 한 시점에 코드는 &lt;b&gt;하나의 가변 참조자(&lt;code&gt;&amp;amp;mut&lt;/code&gt;)&lt;/b&gt; 또는 &lt;b&gt;여러 개의 불변 참조자(&lt;code&gt;&amp;amp;&lt;/code&gt;)&lt;/b&gt; 중 하나만 가질 수 있다. (동시 존재 불가)&lt;/li&gt;
&lt;li&gt;참조자는 항상 유효해야 한다. (Dangling Reference 불가)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;불변 참조 (&lt;code&gt;&amp;amp;T&lt;/code&gt;) vs 가변 참조 (&lt;code&gt;&amp;amp;mut T&lt;/code&gt;)&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 여러 개의 불변 참조 (Read-Only)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽기만 한다면 몇 명이든 상관없습니다.&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;#[test]
fn test_immutable_borrow() {
    let s = String::from(&quot;hello&quot;);
    let r1 = &amp;amp;s; // 불변 참조 1
    let r2 = &amp;amp;s; // 불변 참조 2

    println!(&quot;{}, {}&quot;, r1, r2); // 문제 없음
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 단 하나의 가변 참조 (Read-Write)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정 권한은 오직 한 명에게만 주어집니다. 데이터 레이스(Data Race)를 원천 차단합니다.&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;#[test]
fn test_mutable_borrow() {
    let mut s = String::from(&quot;hello&quot;);

    let r1 = &amp;amp;mut s; 
    // let r2 = &amp;amp;mut s; // 컴파일 에러! (Second mutable borrow occurs here)

    r1.push_str(&quot;, world&quot;);
    println!(&quot;{}&quot;, r1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 불변과 가변의 혼용 불가&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;보고 있는데 누가 수정하면 안 된다&quot;는 원칙입니다.&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;#[test]
fn test_mixed_borrow() {
    let mut s = String::from(&quot;hello&quot;);

    let r1 = &amp;amp;s; // 불변 참조
    let r2 = &amp;amp;s; // 불변 참조
    // let r3 = &amp;amp;mut s; // 컴파일 에러! (불변 참조가 살아있는 동안 가변 참조 불가)

    println!(&quot;{}, {}&quot;, r1, r2); 

    // NLL (Non-Lexical Lifetimes):
    // r1, r2가 여기서 마지막으로 사용되었으므로, 이 시점 이후부터는 가변 참조 가능
    let r3 = &amp;amp;mut s; 
    r3.push_str(&quot; world&quot;);
    println!(&quot;{}&quot;, r3); // 최신 Rust 컴파일러는 여기서 문제 없음
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** Quick Tip (Dangling Reference):**&lt;br /&gt;함수 내에서 생성한 로컬 변수의 &lt;b&gt;참조(reference)&lt;/b&gt;를 리턴하면 안 됩니다. 함수가 끝나면 로컬 변수는 &lt;code&gt;Drop&lt;/code&gt;되는데, 포인터만 리턴하려 하기 때문입니다. 이럴 땐 값을 직접 리턴(Move)하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=13a2a8da28ef195a10ab62f58193ff54&quot;&gt;4.2 References and Borrowing - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gist.github.com/rust-play/13a2a8da28ef195a10ab62f58193ff54&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.3 The Slice Type&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch04-03-slices.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch04-03-slices.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소유권을 갖지 않고(Borrow), 컬렉션(배열, 문자열 등)의 &lt;b&gt;연속된 일부분&lt;/b&gt;을 참조하는 뷰(View)입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문자열 슬라이스 (&lt;code&gt;&amp;amp;str&lt;/code&gt;)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;String&lt;/code&gt;의 일부분을 가리킵니다. 내부적으로 &lt;code&gt;ptr&lt;/code&gt;(시작 위치)와 &lt;code&gt;len&lt;/code&gt;(길이)만 저장합니다.&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;#[test]
fn test_string_slices() {
    let s = String::from(&quot;Hello World&quot;);

    let hello = &amp;amp;s[0..5]; // 인덱스 0부터 4까지
    let world = &amp;amp;s[6..11]; // 인덱스 6부터 10까지

    assert_eq!(hello, &quot;Hello&quot;);
    assert_eq!(world, &quot;World&quot;);

    // 전체 슬라이스 문법
    let slice = &amp;amp;s[..]; 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문자열 리터럴은 슬라이스다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드에 박혀있는 문자열은 바이너리 어딘가를 가리키는 슬라이스입니다.&lt;/p&gt;
&lt;pre class=&quot;openscad&quot;&gt;&lt;code&gt;let s: &amp;amp;str = &quot;Hello&quot;; // s는 바이너리 데이터 영역의 특정 위치를 가리키는 슬라이스
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 슬라이스 (&lt;code&gt;&amp;amp;[T]&lt;/code&gt;)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자열뿐만 아니라 일반 배열도 슬라이싱 가능합니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;#[test]
fn test_array_slices() {
    let a = [1, 2, 3, 4, 5];
    let slice = &amp;amp;a[1..3]; // [2, 3]

    assert_eq!(slice, &amp;amp;[2, 3]);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실전 팁: 함수 파라미터 설계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 파라미터로 문자열을 받을 때 &lt;code&gt;&amp;amp;String&lt;/code&gt;보다 &lt;b&gt;&lt;code&gt;&amp;amp;str&lt;/code&gt;&lt;/b&gt;을 사용하는 것이 훨씬 유연합니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// Bad: String 객체의 참조만 받을 수 있음
fn bad_greet(name: &amp;amp;String) { /* ... */ }

// Good: String의 참조도 받고, 문자열 리터럴(&quot;...&quot;)도 받을 수 있음
fn good_greet(name: &amp;amp;str) { 
    println!(&quot;Hello, {}!&quot;, name);
}

#[test]
fn test_api_design() {
    let my_name = String::from(&quot;Rust&quot;);

    // bad_greet(&quot;Rust&quot;); // 컴파일 에러 (타입 불일치)
    bad_greet(&amp;amp;my_name); // 가능

    good_greet(&quot;Rust&quot;);   // 리터럴 가능 (&amp;amp;str)
    good_greet(&amp;amp;my_name); // String 참조 가능 (Deref Coercion에 의해 &amp;amp;String -&amp;gt; &amp;amp;str 자동 변환)
    good_greet(&amp;amp;my_name[0..1]); // 슬라이스 가능
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=d7e0eae74070a6163798bd36e69e8094&quot;&gt;4.3 The Slice Type - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gist.github.com/rust-play/d7e0eae74070a6163798bd36e69e8094&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;</description>
      <category>Rust</category>
      <category>borrow</category>
      <category>borrowing</category>
      <category>Owner</category>
      <category>ownership</category>
      <category>Reference</category>
      <category>rust</category>
      <category>Slice</category>
      <category>type</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/136</guid>
      <comments>https://iosroid.tistory.com/136#entry136comment</comments>
      <pubDate>Mon, 29 Dec 2025 22:37:55 +0900</pubDate>
    </item>
    <item>
      <title>Rust Common Programming Concepts - Quick Reference</title>
      <link>https://iosroid.tistory.com/135</link>
      <description>&lt;h1&gt;3. Rust Common Programming Concepts - Quick Reference&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 &lt;a href=&quot;https://doc.rust-lang.org/book/ch03-00-common-programming-concepts.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Rust 공식 문서 3장(Common Programming Concepts)&lt;/a&gt;의 내용을 기반으로 빠르게 훑어볼 수 있도록 정리한 요약본입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;img style=&quot;caret-color: transparent; color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot; src=&quot;https://blog.kakaocdn.net/dna/brkSmM/dJMcaajzM62/AAAAAAAAAAAAAAAAAAAAABCIo6LZF4bEUzGbnkhE27J0x3d7f_k6iTooO06sZhVY/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1769871599&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=5BwOrsS8cjEe2U82LcI0hmqXKHw%3D&quot; data-origin-width=&quot;176&quot; data-origin-height=&quot;70&quot; data-is-animation=&quot;false&quot; /&gt;&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.1 Variables and Mutability&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 개념&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기본값: 불변(immutable)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;가변 변수는 &lt;code&gt;mut&lt;/code&gt; 키워드 필요&lt;/li&gt;
&lt;li&gt;섀도잉(shadowing)으로 타입 변경 가능&lt;/li&gt;
&lt;li&gt;상수는 &lt;code&gt;const&lt;/code&gt; 키워드 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;불변 변수 (기본)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_immutable() {
    let x = 5;
    println!(&quot;x = {}&quot;, x);
    // x = 6;  // error[E0384]: cannot assign twice to immutable variable
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;가변 변수&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_mutable() {
    let mut x = 5;
    println!(&quot;Before: {}&quot;, x);
    x = 6;  // OK
    println!(&quot;After: {}&quot;, x);

    // 출력:
    // Before: 5
    // After: 6
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;섀도잉 (Shadowing)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_shadowing() {
    // 1. 같은 타입 섀도잉
    let x = 5;
    let x = x + 1;  // 6
    let x = x * 2;  // 12
    println!(&quot;x = {}&quot;, x);  // 12

    // 2. 다른 타입으로 섀도잉 (타입 변환)
    let spaces = &quot;   &quot;;
    let spaces = spaces.len();  // &amp;amp;str -&amp;gt; usize
    println!(&quot;spaces = {}&quot;, spaces);  // 3

    // 3. mut는 타입 변경 불가
    let mut count = &quot;   &quot;;
    // count = count.len();  // 에러! 타입이 다름
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;섀도잉 스코프&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_shadowing_scope() {
    let x = 5;

    {
        let x = x * 2;  // 내부 스코프에서만 유효
        println!(&quot;Inner: x = {}&quot;, x);  // 10
    }

    println!(&quot;Outer: x = {}&quot;, x);  // 5
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;상수 (Constants)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 전역 상수 - 타입 명시 필수
const MAX_POINTS: u32 = 100_000;
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

fn test_constants() {
    // 함수 내부 상수
    const THRESHOLD: f64 = 0.5;

    println!(&quot;Max points: {}&quot;, MAX_POINTS);
    println!(&quot;Threshold: {}&quot;, THRESHOLD);

    // const는 mut 불가
    // const mut VALUE: i32 = 10;  // 에러
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실전 팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;mut vs shadowing 선택 기준:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;verilog&quot;&gt;&lt;code&gt;fn practical_examples() {
    // mut 사용: 같은 타입의 값을 계속 변경
    let mut counter = 0;
    for _ in 0..10 {
        counter += 1;
    }

    // shadowing 사용: 타입 변환 파이프라인
    let input = &quot;  42  &quot;;
    let input = input.trim();           // &amp;amp;str
    let input = input.parse::&amp;lt;i32&amp;gt;();   // Result&amp;lt;i32, _&amp;gt;
    let input = input.unwrap();         // i32
    println!(&quot;Parsed: {}&quot;, input);

    // shadowing 사용: 중간 계산 결과 저장
    let width = 10;
    let width = width * 2;      // 단위 변환
    let width = width + 5;      // 여백 추가
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;성능 고려사항:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn performance_consideration() {
    // 큰 데이터 구조는 mut가 효율적
    let mut large_vec = vec![0; 1_000_000];
    for i in 0..large_vec.len() {
        large_vec[i] = i;  // in-place 수정
    }

    // 작은 데이터는 불변 + 함수형 스타일도 OK
    let small_vec = vec![1, 2, 3];
    let doubled = small_vec.iter().map(|x| x * 2).collect::&amp;lt;Vec&amp;lt;_&amp;gt;&amp;gt;();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=459fe6de0fc63bd7b89874db3379d8dd&quot;&gt;3.1 Variables and Mutability - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gist.github.com/rust-play/459fe6de0fc63bd7b89874db3379d8dd&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.2 Data Types&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch03-02-data-types.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch03-02-data-types.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 개념&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정적 타입 언어&lt;/b&gt; - 컴파일 시 모든 타입 결정&lt;/li&gt;
&lt;li&gt;타입 추론 지원 (대부분 명시 불필요)&lt;/li&gt;
&lt;li&gt;스칼라 타입: 정수, 부동소수점, 불리언, 문자&lt;/li&gt;
&lt;li&gt;복합 타입: 튜플, 배열&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정수 타입 (Integer Types)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_integer_types() {
    // 부호 있음: i8, i16, i32(기본), i64, i128, isize
    let a: i8 = -128;       // -128 ~ 127
    let b: i32 = 42;        // 기본 타입
    let c: i64 = 1_000_000; // 언더스코어로 가독성

    // 부호 없음: u8, u16, u32, u64, u128, usize
    let d: u8 = 255;        // 0 ~ 255
    let e: u32 = 100_000;

    // 아키텍처 의존 타입
    let f: isize = 100;     // 32bit: i32, 64bit: i64
    let g: usize = 100;     // 배열 인덱스 등에 사용

    // 리터럴 표기법
    let decimal = 98_222;
    let hex = 0xff;             // 255
    let octal = 0o77;           // 63
    let binary = 0b1111_0000;   // 240
    let byte = b'A';            // u8만 가능, 65

    println!(&quot;hex: {}, octal: {}, binary: {}, byte: {}&quot;, 
             hex, octal, binary, byte);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정수 오버플로우 처리&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_overflow() {
    let mut x: u8 = 255;

    // 디버그 모드: panic
    // 릴리즈 모드: 2의 보수 래핑 (0이 됨)
    // x = x + 1;  // 주의

    // 명시적 오버플로우 처리 메서드

    // 1. wrapping_* : 항상 래핑
    let wrapped = x.wrapping_add(1);
    println!(&quot;wrapped: {}&quot;, wrapped);  // 0

    // 2. checked_* : Option 반환
    match x.checked_add(1) {
        Some(val) =&amp;gt; println!(&quot;OK: {}&quot;, val),
        None =&amp;gt; println!(&quot;Overflow detected!&quot;),  // 이 경로 실행
    }

    // 3. saturating_* : 최대/최소값 고정
    let saturated = x.saturating_add(1);
    println!(&quot;saturated: {}&quot;, saturated);  // 255

    // 4. overflowing_* : (결과, 오버플로우 여부) 반환
    let (result, overflowed) = x.overflowing_add(1);
    println!(&quot;result: {}, overflowed: {}&quot;, result, overflowed);
    // result: 0, overflowed: true
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;부동소수점 (Floating-Point Types)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_floating_point() {
    let x = 2.0;        // f64 (기본)
    let y: f32 = 3.0;   // f32

    // 연산
    let sum = 5.0 + 10.0;
    let difference = 95.5 - 4.3;
    let product = 4.0 * 30.0;
    let quotient = 56.7 / 32.2;
    let remainder = 43.0 % 5.0;

    // 부동소수점 비교 주의
    let a = 0.1 + 0.2;
    let b = 0.3;
    // a == b  // false! (부동소수점 오차)

    // 올바른 비교
    let epsilon = f64::EPSILON;
    if (a - b).abs() &amp;lt; epsilon {
        println!(&quot;거의 같음&quot;);
    }

    // 특수값
    let inf = f64::INFINITY;
    let neg_inf = f64::NEG_INFINITY;
    let nan = f64::NAN;

    println!(&quot;Is NaN: {}&quot;, nan.is_nan());
    println!(&quot;Is infinite: {}&quot;, inf.is_infinite());
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;불리언 (Boolean Type)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_boolean() {
    let t = true;
    let f: bool = false;

    // 1바이트 크기
    println!(&quot;Size of bool: {}&quot;, std::mem::size_of::&amp;lt;bool&amp;gt;());  // 1

    // 논리 연산
    let and = t &amp;amp;&amp;amp; f;
    let or = t || f;
    let not = !t;

    // 비교 연산 결과
    let is_greater = 5 &amp;gt; 3;  // true
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문자 (Character Type)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_char() {
    let c = 'z';
    let emoji = ' ';
    let heart = '❤';
    let hangul = '한';

    // 4바이트 유니코드 스칼라 값
    println!(&quot;Size: {}&quot;, std::mem::size_of::&amp;lt;char&amp;gt;());  // 4

    // 문자열과 다름
    let char_literal = 'a';      // char
    let str_literal = &quot;a&quot;;       // &amp;amp;str
    // let wrong = 'ab';         // 에러: 단일 문자만
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;튜플 (Tuple Type)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_tuple() {
    // 1. 기본 선언
    let tup: (i32, f64, u8) = (500, 6.4, 1);

    // 2. 분해 (destructuring)
    let (x, y, z) = tup;
    println!(&quot;x: {}, y: {}, z: {}&quot;, x, y, z);

    // 3. 인덱스 접근 (점 표기법)
    let five_hundred = tup.0;
    let six_point_four = tup.1;
    let one = tup.2;

    // 4. 빈 튜플 = unit 타입
    let unit: () = ();

    // 5. 단일 요소 튜플
    let single = (5,);  // 쉼표 필수
    // let not_tuple = (5);  // 이건 그냥 정수
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;튜플 활용 예제&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn swap(pair: (i32, i32)) -&amp;gt; (i32, i32) {
    let (a, b) = pair;
    (b, a)  // 교환된 튜플 반환
}

fn divide(dividend: i32, divisor: i32) -&amp;gt; (i32, i32) {
    (dividend / divisor, dividend % divisor)  // (몫, 나머지)
}

fn test_tuple_usage() {
    let pair = (5, 10);
    let swapped = swap(pair);
    println!(&quot;Original: {:?}, Swapped: {:?}&quot;, pair, swapped);

    let (quotient, remainder) = divide(17, 5);
    println!(&quot;17 / 5 = {} remainder {}&quot;, quotient, remainder);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 (Array Type)&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;fn test_array() {
    // 1. 기본 선언
    let a = [1, 2, 3, 4, 5];
    let b: [i32; 5] = [1, 2, 3, 4, 5];  // 타입 명시

    // 2. 같은 값으로 초기화
    let zeros = [0; 5];     // [0, 0, 0, 0, 0]
    let threes = [3; 10];   // 10개의 3

    // 3. 인덱스 접근
    let first = a[0];
    let second = a[1];

    // 4. 크기 확인
    println!(&quot;Length: {}&quot;, a.len());

    // 5. 메모리 크기 (스택 할당)
    println!(&quot;Size: {} bytes&quot;, std::mem::size_of_val(&amp;amp;a));
    // i32 * 5 = 20 bytes
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 주의사항&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_array_bounds() {
    let a = [1, 2, 3, 4, 5];

    // 유효한 인덱스
    let element = a[2];
    println!(&quot;Element: {}&quot;, element);

    // 범위 초과 - 런타임 패닉
    // let invalid = a[10];  // thread 'main' panicked

    // 안전한 접근
    if let Some(&amp;amp;value) = a.get(2) {
        println!(&quot;Safe access: {}&quot;, value);
    }

    match a.get(10) {
        Some(&amp;amp;value) =&amp;gt; println!(&quot;Found: {}&quot;, value),
        None =&amp;gt; println!(&quot;Index out of bounds&quot;),
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 반복&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_array_iteration() {
    let a = [10, 20, 30, 40, 50];

    // 1. for 루프로 값 순회
    for element in a {
        println!(&quot;Value: {}&quot;, element);
    }

    // 2. iter()로 참조 순회
    for element in a.iter() {
        println!(&quot;Ref: {}&quot;, element);
    }

    // 3. 인덱스와 값 함께
    for (index, &amp;amp;value) in a.iter().enumerate() {
        println!(&quot;a[{}] = {}&quot;, index, value);
    }

    // 4. 가변 반복 (배열은 고정 크기이므로 드묾)
    let mut b = [1, 2, 3];
    for element in b.iter_mut() {
        *element *= 2;
    }
    println!(&quot;{:?}&quot;, b);  // [2, 4, 6]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 vs 벡터&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;fn test_array_vs_vector() {
    // 배열: 고정 크기, 스택, 컴파일 타임 크기 결정
    let array: [i32; 5] = [1, 2, 3, 4, 5];
    // array.push(6);  // 메서드 없음

    // 벡터: 동적 크기, 힙, 런타임 크기 변경 가능
    let mut vector = vec![1, 2, 3, 4, 5];
    vector.push(6);  // OK
    println!(&quot;Vector: {:?}&quot;, vector);

    // 배열 -&amp;gt; 슬라이스
    let slice: &amp;amp;[i32] = &amp;amp;array[1..3];
    println!(&quot;Slice: {:?}&quot;, slice);  // [2, 3]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;타입 변환&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_type_conversion() {
    // 1. as 키워드 (명시적 캐스팅)
    let integer: i32 = 42;
    let float = integer as f64;
    let byte = integer as u8;

    // 2. 문자열 -&amp;gt; 숫자
    let num: i32 = &quot;42&quot;.parse().unwrap();
    let num: i32 = &quot;42&quot;.parse::&amp;lt;i32&amp;gt;().unwrap();  // 터보피시

    // 3. 숫자 -&amp;gt; 문자열
    let s = 42.to_string();
    let s = format!(&quot;{}&quot;, 42);

    // 4. From/Into 트레이트
    let s = String::from(&quot;hello&quot;);
    let s: String = &quot;hello&quot;.into();

    // 5. TryFrom (실패 가능한 변환)
    use std::convert::TryFrom;
    match i32::try_from(300u16) {
        Ok(n) =&amp;gt; println!(&quot;Converted: {}&quot;, n),
        Err(e) =&amp;gt; println!(&quot;Conversion failed: {}&quot;, e),
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;타입 선택 가이드&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn type_selection_guide() {
    // 정수 기본: i32 (성능과 범위 균형)
    let default_int = 42;

    // 배열 인덱스, 크기: usize
    let arr = [1, 2, 3, 4, 5];
    for i in 0..arr.len() {  // len()은 usize 반환
        println!(&quot;{}&quot;, arr[i]);
    }

    // 바이트 데이터: u8
    let bytes: Vec&amp;lt;u8&amp;gt; = vec![0x48, 0x65, 0x6C, 0x6C, 0x6F];

    // 고정 크기 필요: 배열
    let weekdays: [&amp;amp;str; 7] = [&quot;Mon&quot;, &quot;Tue&quot;, &quot;Wed&quot;, &quot;Thu&quot;, &quot;Fri&quot;, &quot;Sat&quot;, &quot;Sun&quot;];

    // 동적 크기 필요: Vec
    let mut dynamic_list = Vec::new();
    dynamic_list.push(1);
    dynamic_list.push(2);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=c4328028549b424a5abf3562e092206e&quot;&gt;3.2 Data Types - 테스트 코드(Rust Playground)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gist.github.com/rust-play/c4328028549b424a5abf3562e092206e&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.3 Functions&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch03-03-how-functions-work.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch03-03-how-functions-work.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 개념&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;fn&lt;/code&gt; 키워드로 정의&lt;/li&gt;
&lt;li&gt;&lt;b&gt;snake_case&lt;/b&gt; 명명 규칙&lt;/li&gt;
&lt;li&gt;매개변수는 반드시 타입 명시&lt;/li&gt;
&lt;li&gt;반환 타입은 &lt;code&gt;-&amp;gt;&lt;/code&gt; 뒤에 명시&lt;/li&gt;
&lt;li&gt;&lt;b&gt;표현식 기반&lt;/b&gt;: 마지막 표현식이 반환값&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기본 함수 선언&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn main() {
    println!(&quot;Hello from main!&quot;);
    another_function();
    function_with_params(5, 10);
}

fn another_function() {
    println!(&quot;Another function&quot;);
}

fn function_with_params(x: i32, y: i32) {
    println!(&quot;x: {}, y: {}&quot;, x, y);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;함수 반환값&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 1. 표현식으로 반환 (세미콜론 없음)
fn five() -&amp;gt; i32 {
    5  // 표현식
}

fn add(a: i32, b: i32) -&amp;gt; i32 {
    a + b  // 마지막 표현식이 반환값
}

// 2. 명시적 return
fn subtract(a: i32, b: i32) -&amp;gt; i32 {
    return a - b;  // 일찍 반환할 때 유용
}

// 3. 여러 return 경로
fn abs_difference(a: i32, b: i32) -&amp;gt; i32 {
    if a &amp;gt; b {
        return a - b;  // 일찍 반환
    }
    b - a  // 마지막 표현식
}

fn test_returns() {
    assert_eq!(five(), 5);
    assert_eq!(add(2, 3), 5);
    assert_eq!(subtract(10, 3), 7);
    assert_eq!(abs_difference(10, 5), 5);
    assert_eq!(abs_difference(5, 10), 5);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;표현식 vs 문&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_expression_vs_statement() {
    // 문(Statement): 값을 반환하지 않음
    let y = 6;  // 값 바인딩은 문

    // let x = (let y = 6);  // 에러: let은 값이 없음

    // 표현식(Expression): 값을 평가
    let x = 5;  // 5는 표현식
    let y = {
        let x = 3;
        x + 1  // 4를 반환 (세미콜론 없음)
    };
    println!(&quot;y: {}&quot;, y);  // 4

    // 세미콜론이 있으면 ()를 반환
    let z = {
        let x = 3;
        x + 1;  // 세미콜론 -&amp;gt; 문
    };  // z의 타입은 ()
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;세미콜론의 중요성&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 잘못된 반환
fn wrong_return() -&amp;gt; i32 {
    let x = 5;
    x + 1;  // 세미콜론 때문에 () 반환
            // error: mismatched types
}

// 올바른 반환
fn correct_return() -&amp;gt; i32 {
    let x = 5;
    x + 1  // 세미콜론 없음 -&amp;gt; 표현식
}

// 명시적 return 사용
fn explicit_return() -&amp;gt; i32 {
    let x = 5;
    return x + 1;  // 세미콜론 있어도 OK
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;함수 매개변수 패턴&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 1. 튜플 분해
fn print_coordinates((x, y): (i32, i32)) {
    println!(&quot;x: {}, y: {}&quot;, x, y);
}

// 2. 참조 매개변수
fn calculate_length(s: &amp;amp;String) -&amp;gt; usize {
    s.len()
}

// 3. 가변 참조
fn change(s: &amp;amp;mut String) {
    s.push_str(&quot;, world&quot;);
}

fn test_parameters() {
    print_coordinates((10, 20));

    let s = String::from(&quot;hello&quot;);
    let len = calculate_length(&amp;amp;s);
    println!(&quot;Length: {}&quot;, len);

    let mut s = String::from(&quot;hello&quot;);
    change(&amp;amp;mut s);
    println!(&quot;{}&quot;, s);  // &quot;hello, world&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다중 반환값&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 튜플로 여러 값 반환
fn swap(pair: (i32, i32)) -&amp;gt; (i32, i32) {
    let (a, b) = pair;
    (b, a)
}

fn divide_with_remainder(dividend: i32, divisor: i32) -&amp;gt; (i32, i32) {
    (dividend / divisor, dividend % divisor)
}

fn analyze_number(n: i32) -&amp;gt; (bool, bool, i32) {
    let is_positive = n &amp;gt; 0;
    let is_even = n % 2 == 0;
    let absolute = n.abs();
    (is_positive, is_even, absolute)
}

fn test_multiple_returns() {
    let (a, b) = swap((1, 2));
    println!(&quot;Swapped: ({}, {})&quot;, a, b);

    let (quotient, remainder) = divide_with_remainder(17, 5);
    println!(&quot;17 / 5 = {} R {}&quot;, quotient, remainder);

    let (positive, even, abs_val) = analyze_number(-42);
    println!(&quot;Positive: {}, Even: {}, Abs: {}&quot;, positive, even, abs_val);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재귀 함수&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn factorial(n: u32) -&amp;gt; u32 {
    if n == 0 {
        1
    } else {
        n * factorial(n - 1)
    }
}

fn fibonacci(n: u32) -&amp;gt; u32 {
    match n {
        0 =&amp;gt; 0,
        1 =&amp;gt; 1,
        _ =&amp;gt; fibonacci(n - 1) + fibonacci(n - 2),
    }
}

fn test_recursion() {
    println!(&quot;5! = {}&quot;, factorial(5));  // 120
    println!(&quot;fib(10) = {}&quot;, fibonacci(10));  // 55
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;함수 설계 팁&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 작고 명확한 책임
fn is_even(n: i32) -&amp;gt; bool {
    n % 2 == 0
}

fn is_prime(n: u32) -&amp;gt; bool {
    if n &amp;lt; 2 { return false; }
    for i in 2..=(n as f64).sqrt() as u32 {
        if n % i == 0 { return false; }
    }
    true
}

// 조기 반환으로 가독성 향상
fn process_value(value: Option&amp;lt;i32&amp;gt;) -&amp;gt; i32 {
    // None 체크를 먼저
    let val = match value {
        Some(v) =&amp;gt; v,
        None =&amp;gt; return 0,
    };

    // 음수 체크
    if val &amp;lt; 0 {
        return -val;
    }

    // 일반 케이스
    val * 2
}

// 타입 별칭으로 명확성
type Point = (i32, i32);
type Result&amp;lt;T&amp;gt; = std::result::Result&amp;lt;T, String&amp;gt;;

fn distance(p1: Point, p2: Point) -&amp;gt; f64 {
    let (x1, y1) = p1;
    let (x2, y2) = p2;
    (((x2 - x1).pow(2) + (y2 - y1).pow(2)) as f64).sqrt()
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.4 Comments&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch03-04-comments.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch03-04-comments.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 개념&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 주석: &lt;code&gt;//&lt;/code&gt; (한 줄), &lt;code&gt;/* */&lt;/code&gt; (여러 줄)&lt;/li&gt;
&lt;li&gt;문서 주석: &lt;code&gt;///&lt;/code&gt; (외부), &lt;code&gt;//!&lt;/code&gt; (내부)&lt;/li&gt;
&lt;li&gt;문서 주석은 Markdown 지원&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cargo doc&lt;/code&gt;으로 문서 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;일반 주석&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_comments() {
    // 한 줄 주석
    let x = 5;  // 코드 뒤 주석도 가능

    /*
     * 여러 줄 주석
     * 두 번째 줄
     */
    let y = 10;

    /* 중첩 /* 주석 */ 가능 */

    // 코드 주석 처리
    // let unused = 42;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문서 주석 - 외부&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;/// 두 수를 더합니다.
///
/// # Examples
///
/// ```
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
///
/// # Arguments
///
/// * `a` - 첫 번째 숫자
/// * `b` - 두 번째 숫자
///
/// # Returns
///
/// 두 숫자의 합
fn add(a: i32, b: i32) -&amp;gt; i32 {
    a + b
}

/// 숫자가 짝수인지 확인합니다.
///
/// # Panics
///
/// 이 함수는 패닉하지 않습니다.
///
/// # Safety
///
/// 이 함수는 안전합니다.
fn is_even(n: i32) -&amp;gt; bool {
    n % 2 == 0
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문서 주석 - 내부&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;//! 수학 연산을 위한 유틸리티 모듈
//!
//! 이 모듈은 기본적인 수학 연산 함수들을 제공합니다.
//!
//! # Examples
//!
//! ```
//! use my_crate::math;
//! let sum = math::add(2, 3);
//! ```

pub mod math {
    //! 수학 함수 모듈

    /// 덧셈 수행
    pub fn add(a: i32, b: i32) -&amp;gt; i32 {
        a + b
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문서 주석 섹션들&lt;/h3&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;/// 복잡한 계산을 수행합니다.
///
/// # Arguments
///
/// * `input` - 입력값
///
/// # Returns
///
/// 계산 결과
///
/// # Examples
///
/// ```
/// let result = complex_calculation(42);
/// assert_eq!(result, 84);
/// ```
///
/// # Panics
///
/// `input`이 음수일 때 패닉합니다.
///
/// # Errors
///
/// 이 함수는 에러를 반환하지 않습니다.
///
/// # Safety
///
/// 이 함수는 unsafe 블록을 포함하지 않습니다.
fn complex_calculation(input: i32) -&amp;gt; i32 {
    assert!(input &amp;gt;= 0, &quot;Input must be non-negative&quot;);
    input * 2
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주석 작성 팁&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 나쁜 주석: 코드를 그대로 설명
// x에 5를 할당
let x = 5;

// 좋은 주석: 왜 이렇게 했는지 설명
// 성능 최적화를 위해 버퍼 크기를 미리 할당
let mut buffer = Vec::with_capacity(1000);

// 복잡한 로직 설명
// Boyer-Moore 알고리즘을 사용하여 검색 성능 향상
// O(n) -&amp;gt; O(n/m) 복잡도 개선
fn search_pattern(text: &amp;amp;str, pattern: &amp;amp;str) -&amp;gt; Option&amp;lt;usize&amp;gt; {
    // implementation
    None
}

// TODO, FIXME, HACK 표시
// TODO: 에러 처리 추가 필요
// FIXME: 메모리 누수 가능성
// HACK: 임시 방편, 나중에 리팩토링 필요&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.5 Control Flow&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch03-05-control-flow.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://doc.rust-lang.org/book/ch03-05-control-flow.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 개념&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt; - 조건 분기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;loop&lt;/code&gt; - 무한 루프&lt;/li&gt;
&lt;li&gt;&lt;code&gt;while&lt;/code&gt; - 조건 루프&lt;/li&gt;
&lt;li&gt;&lt;code&gt;for&lt;/code&gt; - 컬렉션 순회&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모든 제어문이 표현식&lt;/b&gt; (값을 반환할 수 있음)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;if 표현식&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_if() {
    let number = 6;

    // 1. 기본 if
    if number &amp;lt; 5 {
        println!(&quot;true&quot;);
    } else {
        println!(&quot;false&quot;);
    }

    // 2. else if
    if number % 4 == 0 {
        println!(&quot;divisible by 4&quot;);
    } else if number % 3 == 0 {
        println!(&quot;divisible by 3&quot;);
    } else if number % 2 == 0 {
        println!(&quot;divisible by 2&quot;);
    } else {
        println!(&quot;not divisible by 4, 3, or 2&quot;);
    }

    // 3. if를 표현식으로 사용
    let condition = true;
    let value = if condition { 5 } else { 6 };
    println!(&quot;value: {}&quot;, value);

    // 4. 모든 분기가 같은 타입 반환해야 함
    // let wrong = if condition { 5 } else { &quot;six&quot; };  // 에러
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;if를 이용한 패턴&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_if_patterns() {
    let number = 7;

    // 1. 범위 체크
    let category = if number &amp;lt; 0 {
        &quot;negative&quot;
    } else if number == 0 {
        &quot;zero&quot;
    } else if number &amp;lt; 10 {
        &quot;single digit&quot;
    } else {
        &quot;multiple digits&quot;
    };

    // 2. 조기 반환
    fn check_positive(n: i32) -&amp;gt; Result&amp;lt;i32, String&amp;gt; {
        if n &amp;lt;= 0 {
            return Err(&quot;Not positive&quot;.to_string());
        }
        Ok(n * 2)
    }

    // 3. if let 패턴 (Option/Result 처리)
    let some_value = Some(7);
    if let Some(x) = some_value {
        println!(&quot;Got: {}&quot;, x);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;loop - 무한 루프&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_loop() {
    let mut counter = 0;

    // 1. 기본 무한 루프
    loop {
        counter += 1;
        if counter == 5 {
            break;
        }
    }
    println!(&quot;Counter: {}&quot;, counter);

    // 2. loop에서 값 반환
    let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2;  // 20 반환
        }
    };
    println!(&quot;Result: {}&quot;, result);

    // 3. 레이블로 중첩 루프 제어
    'outer: loop {
        println!(&quot;Outer loop&quot;);

        'inner: loop {
            println!(&quot;Inner loop&quot;);
            break 'outer;  // 외부 루프 탈출
        }

        println!(&quot;This will never print&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;while 루프&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_while() {
    let mut number = 3;

    // 1. 기본 while
    while number != 0 {
        println!(&quot;{}!&quot;, number);
        number -= 1;
    }
    println!(&quot;LIFTOFF!&quot;);

    // 2. while let 패턴
    let mut stack = vec![1, 2, 3];
    while let Some(top) = stack.pop() {
        println!(&quot;Popped: {}&quot;, top);
    }

    // 3. 조건이 복잡한 경우
    let mut x = 0;
    while x &amp;lt; 100 &amp;amp;&amp;amp; x * x &amp;lt; 500 {
        x += 1;
    }
    println!(&quot;x: {}&quot;, x);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;for 루프&lt;/h3&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;fn test_for() {
    let a = [10, 20, 30, 40, 50];

    // 1. 배열 순회 (소유권 이동)
    for element in a {
        println!(&quot;Value: {}&quot;, element);
    }

    // 2. 참조로 순회
    for element in a.iter() {
        println!(&quot;Ref: {}&quot;, element);
    }

    // 3. 범위 순회
    for i in 0..5 {  // 0, 1, 2, 3, 4
        println!(&quot;{}&quot;, i);
    }

    for i in 0..=5 {  // 0, 1, 2, 3, 4, 5 (inclusive)
        println!(&quot;{}&quot;, i);
    }

    // 4. 역순
    for i in (1..4).rev() {  // 3, 2, 1
        println!(&quot;{}!&quot;, i);
    }

    // 5. 인덱스와 값
    for (index, value) in a.iter().enumerate() {
        println!(&quot;a[{}] = {}&quot;, index, value);
    }

    // 6. 가변 반복자
    let mut v = vec![1, 2, 3];
    for item in v.iter_mut() {
        *item *= 2;
    }
    println!(&quot;{:?}&quot;, v);  // [2, 4, 6]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;break와 continue&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn test_break_continue() {
    // 1. continue - 다음 반복으로
    for i in 0..10 {
        if i % 2 == 0 {
            continue;  // 짝수는 건너뛰기
        }
        println!(&quot;Odd: {}&quot;, i);
    }

    // 2. break - 루프 탈출
    let mut sum = 0;
    for i in 1.. {  // 무한 범위
        sum += i;
        if sum &amp;gt; 100 {
            println!(&quot;Stopped at i = {}&quot;, i);
            break;
        }
    }

    // 3. 레이블과 함께 사용
    'outer: for x in 0..5 {
        for y in 0..5 {
            if x * y &amp;gt; 10 {
                break 'outer;  // 외부 루프 탈출
            }
            println!(&quot;x: {}, y: {}&quot;, x, y);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;제어 흐름 비교&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn compare_control_flow() {
    let data = vec![1, 2, 3, 4, 5];

    // 1. 정확한 횟수 반복 -&amp;gt; for
    for i in 0..5 {
        println!(&quot;{}&quot;, i);
    }

    // 2. 조건이 명확 -&amp;gt; while
    let mut count = 0;
    while count &amp;lt; 5 {
        println!(&quot;{}&quot;, count);
        count += 1;
    }

    // 3. 무한 루프, 중간에 break -&amp;gt; loop
    let mut sum = 0;
    loop {
        sum += 1;
        if sum &amp;gt; 100 {
            break;
        }
    }

    // 4. 컬렉션 순회 -&amp;gt; for
    for item in data.iter() {
        println!(&quot;{}&quot;, item);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실전 제어 흐름 패턴&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 1. 입력 검증
fn validate_input(value: i32) -&amp;gt; Result&amp;lt;i32, String&amp;gt; {
    if value &amp;lt; 0 {
        return Err(&quot;Value must be non-negative&quot;.to_string());
    }
    if value &amp;gt; 100 {
        return Err(&quot;Value must be &amp;lt;= 100&quot;.to_string());
    }
    Ok(value)
}

// 2. 재시도 로직
fn retry_with_limit&amp;lt;F&amp;gt;(mut operation: F, max_attempts: u32) -&amp;gt; Result&amp;lt;(), String&amp;gt;
where
    F: FnMut() -&amp;gt; Result&amp;lt;(), String&amp;gt;,
{
    for attempt in 1..=max_attempts {
        match operation() {
            Ok(_) =&amp;gt; return Ok(()),
            Err(e) if attempt == max_attempts =&amp;gt; {
                return Err(format!(&quot;Failed after {} attempts: {}&quot;, max_attempts, e));
            }
            Err(_) =&amp;gt; continue,
        }
    }
    unreachable!()
}

// 3. 조기 반환으로 중첩 제거
fn process_data(data: Option&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;) -&amp;gt; i32 {
    // 중첩된 if
    // if let Some(vec) = data {
    //     if !vec.is_empty() {
    //         if vec[0] &amp;gt; 0 {
    //             return vec[0] * 2;
    //         }
    //     }
    // }

    // 조기 반환
    let vec = match data {
        Some(v) =&amp;gt; v,
        None =&amp;gt; return 0,
    };

    if vec.is_empty() {
        return 0;
    }

    if vec[0] &amp;lt;= 0 {
        return 0;
    }

    vec[0] * 2
}

// 4. 상태 머신 패턴
enum State { Start, Processing, Done }

fn state_machine() {
    let mut state = State::Start;
    let mut count = 0;

    loop {
        state = match state {
            State::Start =&amp;gt; {
                println!(&quot;Starting...&quot;);
                State::Processing
            }
            State::Processing =&amp;gt; {
                count += 1;
                println!(&quot;Processing... {}&quot;, count);
                if count &amp;gt;= 3 {
                    State::Done
                } else {
                    State::Processing
                }
            }
            State::Done =&amp;gt; {
                println!(&quot;Done!&quot;);
                break;
            }
        };
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;종합 예제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;FizzBuzz (다양한 구현)&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 1. if-else 버전
fn fizzbuzz_if(n: u32) {
    for i in 1..=n {
        if i % 15 == 0 {
            println!(&quot;FizzBuzz&quot;);
        } else if i % 3 == 0 {
            println!(&quot;Fizz&quot;);
        } else if i % 5 == 0 {
            println!(&quot;Buzz&quot;);
        } else {
            println!(&quot;{}&quot;, i);
        }
    }
}

// 2. match 버전
fn fizzbuzz_match(n: u32) {
    for i in 1..=n {
        match (i % 3, i % 5) {
            (0, 0) =&amp;gt; println!(&quot;FizzBuzz&quot;),
            (0, _) =&amp;gt; println!(&quot;Fizz&quot;),
            (_, 0) =&amp;gt; println!(&quot;Buzz&quot;),
            _ =&amp;gt; println!(&quot;{}&quot;, i),
        }
    }
}

// 3. 함수형 스타일
fn fizzbuzz_functional(n: u32) {
    (1..=n).for_each(|i| {
        let output = match (i % 3, i % 5) {
            (0, 0) =&amp;gt; &quot;FizzBuzz&quot;.to_string(),
            (0, _) =&amp;gt; &quot;Fizz&quot;.to_string(),
            (_, 0) =&amp;gt; &quot;Buzz&quot;.to_string(),
            _ =&amp;gt; i.to_string(),
        };
        println!(&quot;{}&quot;, output);
    });
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;소수 판별 및 생성&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn is_prime(n: u32) -&amp;gt; bool {
    if n &amp;lt;= 1 {
        return false;
    }
    if n &amp;lt;= 3 {
        return true;
    }
    if n % 2 == 0 || n % 3 == 0 {
        return false;
    }

    let mut i = 5;
    while i * i &amp;lt;= n {
        if n % i == 0 || n % (i + 2) == 0 {
            return false;
        }
        i += 6;
    }

    true
}

fn primes_up_to(limit: u32) -&amp;gt; Vec&amp;lt;u32&amp;gt; {
    (2..=limit).filter(|&amp;amp;n| is_prime(n)).collect()
}

fn nth_prime(n: usize) -&amp;gt; u32 {
    let mut count = 0;
    let mut num = 2;

    loop {
        if is_prime(num) {
            count += 1;
            if count == n {
                return num;
            }
        }
        num += 1;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;계산기&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;fn calculator(a: f64, b: f64, op: char) -&amp;gt; Result&amp;lt;f64, String&amp;gt; {
    match op {
        '+' =&amp;gt; Ok(a + b),
        '-' =&amp;gt; Ok(a - b),
        '*' =&amp;gt; Ok(a * b),
        '/' =&amp;gt; {
            if b == 0.0 {
                Err(&quot;Division by zero&quot;.to_string())
            } else {
                Ok(a / b)
            }
        }
        _ =&amp;gt; Err(format!(&quot;Unknown operator: {}&quot;, op)),
    }
}

fn test_calculator() {
    let operations = vec![
        (10.0, 5.0, '+'),
        (10.0, 5.0, '-'),
        (10.0, 5.0, '*'),
        (10.0, 5.0, '/'),
        (10.0, 0.0, '/'),
    ];

    for (a, b, op) in operations {
        match calculator(a, b, op) {
            Ok(result) =&amp;gt; println!(&quot;{} {} {} = {}&quot;, a, op, b, result),
            Err(e) =&amp;gt; println!(&quot;{} {} {} -&amp;gt; Error: {}&quot;, a, op, b, e),
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실행 테스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 예제를 실행하는 테스트 파일:&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;fn main() {
    println!(&quot;=== 3.1 Variables and Mutability ===&quot;);
    test_immutable();
    test_mutable();
    test_shadowing();
    test_constants();

    println!(&quot;\n=== 3.2 Data Types ===&quot;);
    test_integer_types();
    test_overflow();
    test_floating_point();
    test_tuple();
    test_array();

    println!(&quot;\n=== 3.3 Functions ===&quot;);
    test_returns();
    test_expression_vs_statement();
    test_recursion();

    println!(&quot;\n=== 3.4 Comments ===&quot;);
    // 주석 테스트는 컴파일만 확인

    println!(&quot;\n=== 3.5 Control Flow ===&quot;);
    test_if();
    test_loop();
    test_while();
    test_for();

    println!(&quot;\n=== Comprehensive Examples ===&quot;);
    fizzbuzz_match(15);
    println!(&quot;Is 17 prime? {}&quot;, is_prime(17));
    println!(&quot;Primes up to 20: {:?}&quot;, primes_up_to(20));
    test_calculator();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=c4328028549b424a5abf3562e092206e&quot;&gt;3.3 Functions &amp;amp; 3.5 Control Flow - 테스트 코드&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gist.github.com/rust-play/c4328028549b424a5abf3562e092206e&quot;&gt;Gist&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고 자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch03-00-common-programming-concepts.html&quot;&gt;The Rust Programming Language - Chapter 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/rust-by-example/&quot;&gt;Rust by Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/std/&quot;&gt;std library docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Rust</category>
      <category>comments</category>
      <category>control</category>
      <category>data</category>
      <category>Flow</category>
      <category>functions</category>
      <category>Mutability</category>
      <category>rust</category>
      <category>types</category>
      <category>variables</category>
      <category>러스트</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/135</guid>
      <comments>https://iosroid.tistory.com/135#entry135comment</comments>
      <pubDate>Mon, 22 Dec 2025 17:33:49 +0900</pubDate>
    </item>
    <item>
      <title>PREFERRED_PROVIDER 로 recipe 구분하기</title>
      <link>https://iosroid.tistory.com/133</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;robotlogo.jpg&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGXkOo/btsJoZPMruk/z4CvDiQTm9oDfehhXh6M40/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGXkOo/btsJoZPMruk/z4CvDiQTm9oDfehhXh6M40/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGXkOo/btsJoZPMruk/z4CvDiQTm9oDfehhXh6M40/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGXkOo%2FbtsJoZPMruk%2Fz4CvDiQTm9oDfehhXh6M40%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;512&quot; data-filename=&quot;robotlogo.jpg&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Yocto에서 특정 variable의 선언여부 혹은 그 값에 따라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 목적의 패키지를 제공하는 여러 recipe 중에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다르게 선택하는 옵션을 만들어 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고 나면 간단하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 이해하지 못했을 때는 괜한 삽질을 유도한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순하게 recipe를 분리해서 동일하게 구현할 수 있겠지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Yocto에서 제공하는 virtual target을 사용해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://humblenimble.hashnode.dev/experience-with-preferredprovider&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://humblenimble.hashnode.dev/experience-with-preferredprovider&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1725247885565&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;PREFERRED_PROVIDER User Review&quot; data-og-description=&quot;A guide on using PREFERRED_PROVIDER to implement optional source code and prebuilt package recipes in Yocto Project&quot; data-og-host=&quot;humblenimble.hashnode.dev&quot; data-og-source-url=&quot;https://humblenimble.hashnode.dev/experience-with-preferredprovider&quot; data-og-url=&quot;https://humblenimble.hashnode.dev/experience-with-preferredprovider&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ckHGiA/hyWVYSbmBY/bh2Gcc4jLnORZaKGtEXWj0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bXHZqq/hyWVYLnUBe/0KAeE8vdiVjB6AH84Aq9jk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ba4kgf/hyWZkMO3Mf/onjXIL7ioSoIrgXOkqvtxK/img.jpg?width=1600&amp;amp;height=840&amp;amp;face=0_0_1600_840&quot;&gt;&lt;a href=&quot;https://humblenimble.hashnode.dev/experience-with-preferredprovider&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://humblenimble.hashnode.dev/experience-with-preferredprovider&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ckHGiA/hyWVYSbmBY/bh2Gcc4jLnORZaKGtEXWj0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bXHZqq/hyWVYLnUBe/0KAeE8vdiVjB6AH84Aq9jk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ba4kgf/hyWZkMO3Mf/onjXIL7ioSoIrgXOkqvtxK/img.jpg?width=1600&amp;amp;height=840&amp;amp;face=0_0_1600_840');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PREFERRED_PROVIDER User Review&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A guide on using PREFERRED_PROVIDER to implement optional source code and prebuilt package recipes in Yocto Project&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;humblenimble.hashnode.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Yocto</category>
      <category>depends</category>
      <category>PREFERRED_PROVIDER</category>
      <category>providers</category>
      <category>recipe</category>
      <category>target</category>
      <category>Virtual</category>
      <category>Yocto</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/133</guid>
      <comments>https://iosroid.tistory.com/133#entry133comment</comments>
      <pubDate>Mon, 2 Sep 2024 12:46:59 +0900</pubDate>
    </item>
    <item>
      <title>TMUX 세션별로 환경 분리해서 사용하기</title>
      <link>https://iosroid.tistory.com/132</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;305&quot; data-origin-height=&quot;80&quot;&gt;&lt;a href=&quot;http://tmux.github.io&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMxgbq/btsIBZdenhe/qUj5ZLPZSkIE5odLSVL3N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMxgbq%2FbtsIBZdenhe%2FqUj5ZLPZSkIE5odLSVL3N1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;305&quot; height=&quot;80&quot; data-origin-width=&quot;305&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://tmux.github.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;tmux&lt;/a&gt;를 여러 터미널에서 동시에 다른 환경으로 사용해야 할 상황들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 예제로 개발할 때는 zsh를, 빌드할 때는 오래된 툴체인 때문에 bash를 사용해야 상황이다. (실제로)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한쪽 터미널에서는 build 를 하면서 다른 쪽 터미널에서는 develop을 계속하는 환경이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build 중에 종종 튕기는 악조건 이기에 어떻게든 tmux에 매달려야 한다...... (현실)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tmux.conf 파일에서 아래와 같이 수정하면 default-shell 은 간단히 수정된다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;set-option&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;-g&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;default-shell&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;/bin/zsh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가끔 bash 환경을 써야 할때는 conf 파일을 따로 만들어서 사용하면 된다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;tmux&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;-f&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;~/.tmux_bash.conf&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;zsh 환경을 가끔 쓴다면 반대로 적용하면 되겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 각각의 conf 옵션을 동시에 사용하려면 둘의 환경을 분리해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 소켓의 이름을 다르게 설정하여 서버를 분리해 주는 방법으로 해결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 소켓의 이름은 default 이다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;ls&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;/tmp/tmux-1000/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;default&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 conf 파일을 다르게 적용해도 option 들은 분리가 되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-L&lt;/b&gt; 옵션을 통해서 각각의 소켓을 만든다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;-L socket-name&lt;/b&gt; &lt;br /&gt;tmux stores the server socket in a directory under TMUX_TMPDIR or /tmp if it is unset. The default socket is named default. This option allows a different socket name to be specified, allowing several independent tmux servers to be run. Unlike -S a full path is not necessary: the sockets are all created in a directory tmux-UID under the directory given by TMUX_TMPDIR or in /tmp. The tmux-UID directory is created by tmux and must not be world readable, writable or executable.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;tmux&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;-L&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;devel&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;tmux&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;-L&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;-f&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;~/.tmux_bash.conf&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 이름으로 생성된 소켓을 통해 conf 환경이 분리되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하네...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build와 devel 소켓이 생성되었다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;ls&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;/tmp/tmux-1000/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt; &lt;span style=&quot;background-color: #1e1e1e; color: #ce9178; text-align: start;&quot;&gt;build&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;default&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;devel&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;tmux&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;-L&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;devel&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;list-sessions&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;0:&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;windows&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (created &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;Wed&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;Jul&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;17&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;11:21:23&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;2024&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;) (&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;attached&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;tmux&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;-L&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;list-sessions&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;0:&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;windows&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (created &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;Wed&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;Jul&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;17&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;11:22:00&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;2024&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;) (&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;attached&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;alias로 편하게&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;tmux-dev&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'tmux -L devel'&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;tmux-build&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'tmux -L build'&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>tips</category>
      <category>Name</category>
      <category>socket</category>
      <category>tmux</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/132</guid>
      <comments>https://iosroid.tistory.com/132#entry132comment</comments>
      <pubDate>Wed, 17 Jul 2024 22:00:55 +0900</pubDate>
    </item>
    <item>
      <title>tkinter와 cffi 간단한 툴 제작</title>
      <link>https://iosroid.tistory.com/131</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;UI? tkinter와 pyqt 중 아래의 이유로 tkinter 선택&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;UI 복잡도가 낮아서 문서만 보고 바로 사용 가능
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단순한 UI 요소들을 그리드 구조로&lt;span&gt;&amp;nbsp;&lt;/span&gt;위치만 잘 잡아주면 되서 편함&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alejandroautalan/pygubu&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Pygubu라는&lt;/a&gt; UI 제작 툴도 있음.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;XML 파일로 UI 구조를 생성해 줌.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alejandroautalan/pygubu-designer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pygubu-designer로&lt;/a&gt; 직관적인 UI 구성 가능.&lt;/li&gt;
&lt;li&gt;XML 구조가 코드로 뚝딱 뚝딱 만든 것보다 더 복잡하게 느껴져서 안 씀.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추가 설치 필요 없음.&lt;/li&gt;
&lt;li&gt;라이센스 편함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;cffi로 c 코드 함수 사용.&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;처리 속도에서 우월.&lt;/li&gt;
&lt;li&gt;처리 데이터의 양이 많을수록 확실한 차이가 남.&lt;/li&gt;
&lt;li&gt;ctypes와 비교했고, 함수선언이 cffi 가 c 코드 그대로 사용해서 익숙해 보였음.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1712825528528&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cffi
my_int = ffi.new(&quot;int[1]&quot;)
my_int[0] = 5

# ctypes
my_int = ctypes.c_int(5)
my_int_ptr = ctypes.pointer(my_int)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C 함수 X() 선언.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 라이브러리의 헤더에 정의된 내용.&lt;/p&gt;
&lt;pre id=&quot;code_1712823604652&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ffi.cdef(&quot;&quot;&quot;
int x(
	uint8_t *buf,
	uint32_t *out_size,
	const uint8_t *data,
	uint32_t data_size,
	const uint8_t *p,
	uint32_t p_size,
	uint32_t t,
	uint32_t e,
	const uint8_t *u,
	uint32_t u_size
	);
&quot;&quot;&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 넘겨받는 buf 에는 메모리 공간을 미리 할당.&lt;/p&gt;
&lt;pre id=&quot;code_1712823985965&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;out_buf = ffi.new(&quot;char[]&quot;, 512)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C의 배열 변수에 데이터를 넣듯이 파이썬 변수에도 값을 저장해 줘서 전달.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 공간은 미리 할당.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 변수 dataBytes는 bytearray 타입.&lt;/p&gt;
&lt;pre id=&quot;code_1712824193277&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data = ffi.new(&quot;uint8_t[]&quot;, len(dataBytes))
idx = 0
for d in dataBytes:
    data[idx] = d
    idx += 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상수값이나 NULL 은 직접 값으로 전달 가능.&lt;/p&gt;
&lt;pre id=&quot;code_1712824580409&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;result = mylib.x(
        out_buf,
        out_size,
        data,
        len(dataBytes),
        ffi.NULL,
        0,
        0x1010,
        1,
        ffi.NULL,
        0
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C 함수의 리턴값이 result에 저장됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;out_buf는 cffi의 타입(cdata)이므로 &lt;a href=&quot;https://cffi.readthedocs.io/en/latest/ref.html#ffi-string-ffi-unpack&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;unpack&lt;/a&gt;을 이용해 데이터를 파이썬 변수로 저장해야 함.&lt;/p&gt;
&lt;pre id=&quot;code_1712824695139&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;outBufUnpack = ffi.unpack(out_buf, out_size[0])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;out_size는 out_buf의 크기인데 &lt;span&gt;uint32_t* 타입이라 [0]로 값을 읽어올 수 있음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cffi.readthedocs.io/en/latest/ref.html#ffi-new&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ffi.new&lt;/a&gt;로 생성한 변수는 &lt;a href=&quot;https://cffi.readthedocs.io/en/latest/ref.html#ffi-release-and-the-context-manager&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ffi.release&lt;/a&gt;로 메모리 해제함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명에선 아래와 같다. 예상 가능한 시점의 빠른 해제를 위해 넣어줌.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;The normal Python destructor of the cdata object releases the same resources, but this allows the releasing to occur at a known time, as opposed as at an unspecified point in the future.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>python</category>
      <category>cffi</category>
      <category>python</category>
      <category>Tkinter</category>
      <category>UI</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/131</guid>
      <comments>https://iosroid.tistory.com/131#entry131comment</comments>
      <pubDate>Thu, 11 Apr 2024 19:20:40 +0900</pubDate>
    </item>
    <item>
      <title>The 2024 MAD Landscape</title>
      <link>https://iosroid.tistory.com/130</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 Machine Learning, AI &amp;amp; Data 업계 지도와 최신 트렌드에 관한 글.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mattturck.com/mad2024/&quot;&gt;Full Steam Ahead: The 2024 MAD (Machine Learning, AI &amp;amp; Data) Landscape &amp;ndash; Matt Turck&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712639137960&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Full Steam Ahead: The 2024 MAD (Machine Learning, AI &amp;amp; Data) Landscape&quot; data-og-description=&quot;This is our tenth annual landscape and &amp;ldquo;state of the union&amp;rdquo; of the data, analytics, machine learning and AI ecosystem. In 10+ years covering the space, things have never been as exciting and promising as they are today. All trends and subtrends we desc&quot; data-og-host=&quot;mattturck.com&quot; data-og-source-url=&quot;https://mattturck.com/mad2024/&quot; data-og-url=&quot;https://mattturck.com/mad2024/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bEL5cy/hyVMUCmz6W/UXk7tDuPkjL5us44K13cXK/img.jpg?width=1024&amp;amp;height=534&amp;amp;face=0_0_1024_534,https://scrap.kakaocdn.net/dn/c4ctO1/hyVMWNGCyo/IlGRugJMK7g5zOA93IZ8w0/img.jpg?width=1024&amp;amp;height=534&amp;amp;face=0_0_1024_534,https://scrap.kakaocdn.net/dn/d2serP/hyVMLejtW3/wJjJXNZ8pH4gJJVVKk3Aw0/img.jpg?width=1024&amp;amp;height=534&amp;amp;face=0_0_1024_534&quot;&gt;&lt;a href=&quot;https://mattturck.com/mad2024/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mattturck.com/mad2024/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bEL5cy/hyVMUCmz6W/UXk7tDuPkjL5us44K13cXK/img.jpg?width=1024&amp;amp;height=534&amp;amp;face=0_0_1024_534,https://scrap.kakaocdn.net/dn/c4ctO1/hyVMWNGCyo/IlGRugJMK7g5zOA93IZ8w0/img.jpg?width=1024&amp;amp;height=534&amp;amp;face=0_0_1024_534,https://scrap.kakaocdn.net/dn/d2serP/hyVMLejtW3/wJjJXNZ8pH4gJJVVKk3Aw0/img.jpg?width=1024&amp;amp;height=534&amp;amp;face=0_0_1024_534');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Full Steam Ahead: The 2024 MAD (Machine Learning, AI &amp;amp; Data) Landscape&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This is our tenth annual landscape and &amp;ldquo;state of the union&amp;rdquo; of the data, analytics, machine learning and AI ecosystem. In 10+ years covering the space, things have never been as exciting and promising as they are today. All trends and subtrends we desc&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mattturck.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GeekNews 에서 한글로 요약 정리된 글&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://news.hada.io/topic?id=14209&quot;&gt;2024년 ML/AI/Data 업계 지도와 최신 트렌드 | GeekNews (hada.io)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712639235705&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;2024년 ML/AI/Data 업계 지도와 최신 트렌드 | GeekNews&quot; data-og-description=&quot;이미지 한장으로 정리한 2024년 MAD(ML,AI,Data) 업계 지도 및 올해의 24가지 테마 설명[Part I : Landscape]2012년 최초 버전에서는 139개 기업만 있었으나, 2024년 MAD 생태계에는 2,011개 기업이 포함됨이는 작&quot; data-og-host=&quot;news.hada.io&quot; data-og-source-url=&quot;https://news.hada.io/topic?id=14209&quot; data-og-url=&quot;https://news.hada.io/topic?id=14209&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bzYKHo/hyVMLrRij0/AON1xLkMfCWAUYyIyuqvjk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bnA4EF/hyVMWUtkI9/NmUV8LyXDvVZck4urowKb1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://news.hada.io/topic?id=14209&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://news.hada.io/topic?id=14209&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bzYKHo/hyVMLrRij0/AON1xLkMfCWAUYyIyuqvjk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bnA4EF/hyVMWUtkI9/NmUV8LyXDvVZck4urowKb1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2024년 ML/AI/Data 업계 지도와 최신 트렌드 | GeekNews&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미지 한장으로 정리한 2024년 MAD(ML,AI,Data) 업계 지도 및 올해의 24가지 테마 설명[Part I : Landscape]2012년 최초 버전에서는 139개 기업만 있었으나, 2024년 MAD 생태계에는 2,011개 기업이 포함됨이는 작&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;news.hada.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GeekNews 페이지에서 인상적인 글귀:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2012년&amp;nbsp;최초&amp;nbsp;버전에서는&amp;nbsp;139개&amp;nbsp;기업만&amp;nbsp;있었으나,&amp;nbsp;2024년&amp;nbsp;MAD&amp;nbsp;생태계에는&amp;nbsp;2,011개&amp;nbsp;기업이&amp;nbsp;포함됨&lt;/li&gt;
&lt;li&gt;애플리케이션&amp;nbsp;계층의&amp;nbsp;모든&amp;nbsp;기업이&amp;nbsp;이제&amp;nbsp;스스로를&amp;nbsp;&quot;AI&amp;nbsp;기업&quot;이라고&amp;nbsp;칭함&lt;/li&gt;
&lt;li&gt;현재&amp;nbsp;비구조화된&amp;nbsp;데이터(ML/AI)는&amp;nbsp;주목받고&amp;nbsp;있지만,&amp;nbsp;구조화된&amp;nbsp;데이터(모던&amp;nbsp;데이터&amp;nbsp;스택&amp;nbsp;등)는&amp;nbsp;그렇지&amp;nbsp;않음&lt;/li&gt;
&lt;li&gt;데이터&amp;nbsp;인프라&amp;nbsp;업계는&amp;nbsp;마침내&amp;nbsp;일정&amp;nbsp;수준의&amp;nbsp;통합을&amp;nbsp;경험하게&amp;nbsp;될&amp;nbsp;것임&lt;/li&gt;
&lt;li&gt;모두가 LLM의 힘을 원하지만 자신들의(기업) 데이터로 학습된 모델을 원함&lt;/li&gt;
&lt;li&gt;한편&amp;nbsp;새로운&amp;nbsp;세대의&amp;nbsp;AI&amp;nbsp;인프라&amp;nbsp;스타트업들이&amp;nbsp;여러&amp;nbsp;영역에서&amp;nbsp;등장하고&amp;nbsp;있음&lt;/li&gt;
&lt;li&gt;하이프는&amp;nbsp;늘&amp;nbsp;그렇듯&amp;nbsp;여러&amp;nbsp;장점(&quot;광적&amp;nbsp;열정&amp;nbsp;없인&amp;nbsp;위대한&amp;nbsp;성취&amp;nbsp;없다&quot;,&amp;nbsp;&quot;백&amp;nbsp;가지&amp;nbsp;꽃이&amp;nbsp;피게&amp;nbsp;하라&quot;식의&amp;nbsp;야심찬&amp;nbsp;프로젝트에&amp;nbsp;자금이&amp;nbsp;몰림)과&amp;nbsp;단점(하룻밤에&amp;nbsp;모두가&amp;nbsp;AI&amp;nbsp;전문가로&amp;nbsp;둔갑,&amp;nbsp;모든&amp;nbsp;스타트업이&amp;nbsp;AI&amp;nbsp;기업이&amp;nbsp;됨,&amp;nbsp;AI&amp;nbsp;콘퍼런스/팟캐스트/뉴스레터&amp;nbsp;범람,&amp;nbsp;AI&amp;nbsp;마켓맵&amp;nbsp;홍수)을&amp;nbsp;동반함&lt;/li&gt;
&lt;li&gt;소비자 앱은 이탈률이 높음. 단순 호기심은 아니었나?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개인적으로나 업무상으로나 생성형 AI를 어떻게 활용해야 할지 잘 모르겠다는 사람이 많음&lt;/li&gt;
&lt;li&gt;최고의&amp;nbsp;AI&amp;nbsp;전문가가&amp;nbsp;만든&amp;nbsp;제품이라도&amp;nbsp;모두&amp;nbsp;마법&amp;nbsp;같진&amp;nbsp;않을&amp;nbsp;것임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;지난&amp;nbsp;18개월간&amp;nbsp;가장&amp;nbsp;흔한&amp;nbsp;질문은&amp;nbsp;이것:&amp;nbsp;우리는&amp;nbsp;결국&amp;nbsp;평준화될&amp;nbsp;제품에&amp;nbsp;엄청난&amp;nbsp;자본이&amp;nbsp;소각되는&amp;nbsp;광경을&amp;nbsp;보고&amp;nbsp;있는&amp;nbsp;걸까?&amp;nbsp;아니면&amp;nbsp;이&amp;nbsp;LLM&amp;nbsp;기업들이&amp;nbsp;새로운&amp;nbsp;AWS,&amp;nbsp;Azure,&amp;nbsp;GCP가&amp;nbsp;되는&amp;nbsp;걸까?&lt;/li&gt;
&lt;li&gt;LLM&amp;nbsp;기업&amp;nbsp;입장에선&amp;nbsp;골치&amp;nbsp;아픈&amp;nbsp;사실은,&amp;nbsp;어느&amp;nbsp;LLM도&amp;nbsp;지속적인&amp;nbsp;성능&amp;nbsp;우위를&amp;nbsp;구축하지&amp;nbsp;못하는&amp;nbsp;듯&amp;nbsp;보인다는&amp;nbsp;점&lt;/li&gt;
&lt;li&gt;기업에서는 이런 다양한 모델을 조합한 하이브리드 아키텍처로 빠르게 진화하는 중&lt;/li&gt;
&lt;li&gt;가격이 내려가고는 있지만 대형 사유 LLM은 여전히 비싸고 지연 문제도 있어서, 사용자/고객은 점점 더 다양한 모델을 조합해 배포하게 될 것임
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대형/소형,&amp;nbsp;상용/오픈소스,&amp;nbsp;범용/특화&amp;nbsp;모델을&amp;nbsp;필요와&amp;nbsp;예산에&amp;nbsp;맞게&amp;nbsp;조합해&amp;nbsp;사용하는&amp;nbsp;추세임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ChatGPT의&amp;nbsp;등장으로&amp;nbsp;그&amp;nbsp;전까지&amp;nbsp;첨단으로&amp;nbsp;여겨지던&amp;nbsp;AI&amp;nbsp;기술들이&amp;nbsp;하루아침에&amp;nbsp;&quot;전통적&amp;nbsp;AI&quot;로&amp;nbsp;불리게&amp;nbsp;됨&lt;/li&gt;
&lt;li&gt;앞으로&amp;nbsp;기업들은&amp;nbsp;LLM을&amp;nbsp;어떤&amp;nbsp;작업에,&amp;nbsp;전통적&amp;nbsp;AI&amp;nbsp;모델을&amp;nbsp;어떤&amp;nbsp;작업에&amp;nbsp;사용할지,&amp;nbsp;그리고&amp;nbsp;둘을&amp;nbsp;어떻게&amp;nbsp;결합할지&amp;nbsp;고민하게&amp;nbsp;될&amp;nbsp;것임&lt;/li&gt;
&lt;li&gt;스타트업&amp;nbsp;생태계&amp;nbsp;참여자&amp;nbsp;입장에서는&amp;nbsp;GPT-5의&amp;nbsp;성능이&amp;nbsp;GPT-4&amp;nbsp;대비&amp;nbsp;얼마나&amp;nbsp;향상될지가&amp;nbsp;기술&amp;nbsp;발전&amp;nbsp;속도의&amp;nbsp;바로미터가&amp;nbsp;될&amp;nbsp;것임&lt;/li&gt;
&lt;li&gt;시장은&amp;nbsp;자정&amp;nbsp;작용을&amp;nbsp;통해&amp;nbsp;소수의&amp;nbsp;성공적인&amp;nbsp;오픈소스&amp;nbsp;프로젝트만&amp;nbsp;클라우드&amp;nbsp;기업&amp;nbsp;등의&amp;nbsp;지원을&amp;nbsp;받게&amp;nbsp;될&amp;nbsp;것임.&amp;nbsp;그러나&amp;nbsp;그때까지는&amp;nbsp;혼란스러운&amp;nbsp;상황이&amp;nbsp;이어질&amp;nbsp;전망&lt;/li&gt;
&lt;li&gt;공급자 입장에서는 AI 구축/서비스 비용이 여전히 높음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Anthropic은 매출의 절반 이상을 클라우드 비용으로 지출했다고 함&lt;/li&gt;
&lt;li&gt;데이터&amp;nbsp;라이선싱&amp;nbsp;비용도&amp;nbsp;만만치&amp;nbsp;않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI가 너무 많은 걸 하려는 건 아닌가? 수직적으로나 수평적으로 AI의 모든 것을 하겠다는 것 같은데 무리수 아닌지?&lt;/li&gt;
&lt;li&gt;OpenAI와&amp;nbsp;MS가&amp;nbsp;결별할까?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문 작성자 &lt;a href=&quot;https://twitter.com/mattturck&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;mattturck&lt;/a&gt; 님과&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;GeekNews&lt;span&gt;&amp;nbsp;에게&lt;/span&gt;&lt;/span&gt;&amp;nbsp;감사함을 표합니다.&lt;/p&gt;</description>
      <category>Blogs I read this week</category>
      <category>AI</category>
      <category>DeepLearning</category>
      <category>ML</category>
      <category>업계</category>
      <category>인공지능</category>
      <category>트렌드</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/130</guid>
      <comments>https://iosroid.tistory.com/130#entry130comment</comments>
      <pubDate>Tue, 9 Apr 2024 14:24:21 +0900</pubDate>
    </item>
    <item>
      <title>python2 기본 환경에서 python3 사용하려면 feat. AI</title>
      <link>https://iosroid.tistory.com/129</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;python2 가 기본인 시스템에서 잠시 python3 를 사용해야 할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에서 가장 흔하게 검색되었던 결과는&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;update-alternatives 가 많이 보였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얘도 결국 링크를 변경할 뿐이지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/usr/bin/python -&amp;gt; /etc/alternatives/python -&amp;gt;&amp;nbsp;/usr/bin/python2.7&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굳이 잠깐의 실행을 위해 /usr/bin 을 건들고 싶지 않은데?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 검색하면 나오는 건&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual environment 를 사용해라 인데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굳이 또 새로운 패키지를 설치하면서까지 필요한&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 대단한 일도 아닌데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shebang 을 바꿔라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 python2/3 문법이 달라 나오는 에러는 그 자체로 분노유발...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등잔밑이 어둡다의 경우인지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 쉽고 당연하다고 생각해서 잊고 지낸 대가인지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shell 에는 alias 가 있다... 하하.&lt;/p&gt;
&lt;pre id=&quot;code_1710229811460&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;alias python=python3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 두고 뭔 짓을 해온 것인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이걸 MS copilot 이 딴 거 다 제쳐두고 딱 이것만 답변을 해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와우..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;군더더기 없고 확실하게 답을 주다니..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문을 잘한 건가? 싶어 다른 애들에게도 물어보니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ChatGPT는 한글로 물어보니 'python3' 명령어를 쓰세요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtualenv&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt; 또는 &lt;/span&gt;venv&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt;를 사용하&lt;/span&gt;세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영어로 물어보니 위에서 말한 세 가지 방법을 다 나열해 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비영어권에겐 좀 불친절...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Perplexity는 update-alternatives 만 추천.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mistral.ai 는 python3 명령어를 알려주고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 다 맞는 답이긴 하지만&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비록 우연일지라도 바로 내가 필요한 답을 준 Copilot에게 칭찬.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>python</category>
      <category>alias</category>
      <category>ChatGPT</category>
      <category>Copilot</category>
      <category>mistral.ai</category>
      <category>perplexity</category>
      <category>python</category>
      <category>python2</category>
      <category>python3</category>
      <category>shell</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/129</guid>
      <comments>https://iosroid.tistory.com/129#entry129comment</comments>
      <pubDate>Tue, 12 Mar 2024 16:58:36 +0900</pubDate>
    </item>
    <item>
      <title>ubuntu 20.04 watchdog bug soft lockup stuck for CPU</title>
      <link>https://iosroid.tistory.com/126</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1748337-20220923100833919-183196813.png&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rV4CT/btr0eTVxNv8/YsdlSkyfxdWB7zUkKZxxdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rV4CT/btr0eTVxNv8/YsdlSkyfxdWB7zUkKZxxdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rV4CT/btr0eTVxNv8/YsdlSkyfxdWB7zUkKZxxdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrV4CT%2Fbtr0eTVxNv8%2FYsdlSkyfxdWB7zUkKZxxdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;377&quot; height=&quot;185&quot; data-filename=&quot;1748337-20220923100833919-183196813.png&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;System:Virtualbox Guest Ubuntu 20.04&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lot of system reports poped up after log-in.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Message contains the words watchdog, soft lockup, stuck for CPU something something...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;systemd-logind crashed with sigabrt in epoll_wait()&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Host cpu usage goes high, Guest OS no response.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Not happen in Ubuntu 18.04.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tried first.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sangchul.kr/460?category=961091&quot;&gt;[리눅스] watchdog: BUG: soft lockup - CPU#0 stuck for 63s! (sangchul.kr)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677033213649&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[리눅스] watchdog: BUG: soft lockup - CPU#0 stuck for 63s!&quot; data-og-description=&quot;watchdog: BUG: soft lockup 에러 테스트 환경 $ cat /etc/os-release PRETTY_NAME=&amp;quot;Ubuntu 22.04.1 LTS&amp;quot; NAME=&amp;quot;Ubuntu&amp;quot; VERSION_ID=&amp;quot;22.04&amp;quot; VERSION=&amp;quot;22.04.1 LTS (Jammy Jellyfish)&amp;quot; VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL=&amp;quot;https://www.ubuntu.&quot; data-og-host=&quot;sangchul.kr&quot; data-og-source-url=&quot;https://sangchul.kr/460?category=961091&quot; data-og-url=&quot;https://sangchul.kr/460&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3xqep/hyRIwrIUtt/ktHko5i2VLhnaKM4e67Ms1/img.png?width=82&amp;amp;height=68&amp;amp;face=0_0_82_68,https://scrap.kakaocdn.net/dn/bE1Dn9/hyRIAVcOj7/nsXQMwQ0iW8OKC11vF61u1/img.png?width=82&amp;amp;height=68&amp;amp;face=0_0_82_68,https://scrap.kakaocdn.net/dn/d3hM9x/hyRIqLPJMN/VDZvR7TpGrmzp1ihY7YQRK/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://sangchul.kr/460?category=961091&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sangchul.kr/460?category=961091&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3xqep/hyRIwrIUtt/ktHko5i2VLhnaKM4e67Ms1/img.png?width=82&amp;amp;height=68&amp;amp;face=0_0_82_68,https://scrap.kakaocdn.net/dn/bE1Dn9/hyRIAVcOj7/nsXQMwQ0iW8OKC11vF61u1/img.png?width=82&amp;amp;height=68&amp;amp;face=0_0_82_68,https://scrap.kakaocdn.net/dn/d3hM9x/hyRIqLPJMN/VDZvR7TpGrmzp1ihY7YQRK/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[리눅스] watchdog: BUG: soft lockup - CPU#0 stuck for 63s!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;watchdog: BUG: soft lockup 에러 테스트 환경 $ cat /etc/os-release PRETTY_NAME=&quot;Ubuntu 22.04.1 LTS&quot; NAME=&quot;Ubuntu&quot; VERSION_ID=&quot;22.04&quot; VERSION=&quot;22.04.1 LTS (Jammy Jellyfish)&quot; VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL=&quot;https://www.ubuntu.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sangchul.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nothing changed&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tried second.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/systemd/systemd/issues/9431#issuecomment-412195708&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/systemd/systemd/issues/9431#issuecomment-412195708&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677033198673&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;[Ubuntu 18.04] systemd-logind crashed with SIGABRT in __libc_connect()  &amp;middot; Issue #9431 &amp;middot; systemd/systemd&quot; data-og-description=&quot;systemd version the issue has been seen with v237 https://launchpad.net/ubuntu/+source/systemd/237-3ubuntu10 Used distribution Ubuntu 18.04 Ubuntu bug: https://bugs.launchpad.net/ubuntu/+source/sys...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/systemd/systemd/issues/9431#issuecomment-412195708&quot; data-og-url=&quot;https://github.com/systemd/systemd/issues/9431&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/baUrvV/hyRHmjXAYG/iMm8jWIF0MrJg3OFfiZoU1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/systemd/systemd/issues/9431#issuecomment-412195708&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/systemd/systemd/issues/9431#issuecomment-412195708&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/baUrvV/hyRHmjXAYG/iMm8jWIF0MrJg3OFfiZoU1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Ubuntu 18.04] systemd-logind crashed with SIGABRT in __libc_connect() &amp;middot; Issue #9431 &amp;middot; systemd/systemd&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;systemd version the issue has been seen with v237 https://launchpad.net/ubuntu/+source/systemd/237-3ubuntu10 Used distribution Ubuntu 18.04 Ubuntu bug: https://bugs.launchpad.net/ubuntu/+source/sys...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It worked for me.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Another solution.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mryeo.tistory.com/17&quot;&gt;[리눅스 우분투] 시스템 프로그램 오류 (watchdog: BUG: soft lockup) 해결하기 (Linux ubuntu) (tistory.com)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677033419623&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[리눅스 우분투] 시스템 프로그램 오류 (watchdog: BUG: soft lockup) 해결하기 (Linux ubuntu)&quot; data-og-description=&quot;안녕하세요, 오늘은 리눅스 우분투에서 시스템 프로그램 오류를 해결하는 방법에 대해 포스팅 해보도록 하겠습니다. 우분투를 시작할 때마다 아래와 같은 팝업 메시지 때문에 골치 아팠던 적이&quot; data-og-host=&quot;mryeo.tistory.com&quot; data-og-source-url=&quot;https://mryeo.tistory.com/17&quot; data-og-url=&quot;https://mryeo.tistory.com/17&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/RGq8Q/hyRIA1Y8HE/5QKPuvKIJ1nHIW9Aynw0CK/img.png?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/XtfLv/hyRIyJRpjs/oigspLV8qCYMJLxe0MZrkK/img.png?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/8M8Hl/hyRHlSTLAF/KyHKp2LHPv84JY3Gl66t01/img.png?width=1040&amp;amp;height=282&amp;amp;face=0_0_1040_282&quot;&gt;&lt;a href=&quot;https://mryeo.tistory.com/17&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mryeo.tistory.com/17&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/RGq8Q/hyRIA1Y8HE/5QKPuvKIJ1nHIW9Aynw0CK/img.png?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/XtfLv/hyRIyJRpjs/oigspLV8qCYMJLxe0MZrkK/img.png?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/8M8Hl/hyRHlSTLAF/KyHKp2LHPv84JY3Gl66t01/img.png?width=1040&amp;amp;height=282&amp;amp;face=0_0_1040_282');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[리눅스 우분투] 시스템 프로그램 오류 (watchdog: BUG: soft lockup) 해결하기 (Linux ubuntu)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요, 오늘은 리눅스 우분투에서 시스템 프로그램 오류를 해결하는 방법에 대해 포스팅 해보도록 하겠습니다. 우분투를 시작할 때마다 아래와 같은 팝업 메시지 때문에 골치 아팠던 적이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mryeo.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>tips</category>
      <category>20.04</category>
      <category>CPU</category>
      <category>Crash</category>
      <category>lockup</category>
      <category>SIGABRT</category>
      <category>soft</category>
      <category>stuck</category>
      <category>systemd</category>
      <category>ubuntu</category>
      <category>WatchDog</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/126</guid>
      <comments>https://iosroid.tistory.com/126#entry126comment</comments>
      <pubDate>Wed, 22 Feb 2023 11:57:54 +0900</pubDate>
    </item>
    <item>
      <title>기존 리눅스 명령어 대체 툴</title>
      <link>https://iosroid.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/LINUX-%F0%9F%93%9A-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EB%88%85%EC%8A%A4-%ED%84%B0%EB%AF%B8%EB%84%90%EC%9D%84-%ED%99%94%EB%A0%A4%ED%95%98%EA%B2%8C-%F0%9F%90%A7-%EC%B5%9C%EC%8B%A0%EC%8B%9D-CLI-%EB%AA%A8%EC%9D%8C&quot;&gt;[Modern Linux]   모던 리눅스 - 최신식 리눅스 명령어 모음 (tistory.com)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1673343021729&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Modern Linux]   모던 리눅스 - 최신식 리눅스 명령어 모음&quot; data-og-description=&quot;모던 리눅스/유닉스 명령어 대부분의 리눅스 강의나 수업에서는 초창기부터 있던 전통적인 CLI 명령어(ls, cd, pwd, cat, cp, mv, rm, mkdir, ...등) 위주로 알려준다. 그러나 이 오래된 명령어들은 작성된&quot; data-og-host=&quot;inpa.tistory.com&quot; data-og-source-url=&quot;https://inpa.tistory.com/entry/LINUX-%F0%9F%93%9A-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EB%88%85%EC%8A%A4-%ED%84%B0%EB%AF%B8%EB%84%90%EC%9D%84-%ED%99%94%EB%A0%A4%ED%95%98%EA%B2%8C-%F0%9F%90%A7-%EC%B5%9C%EC%8B%A0%EC%8B%9D-CLI-%EB%AA%A8%EC%9D%8C&quot; data-og-url=&quot;https://inpa.tistory.com/entry/LINUX-%F0%9F%93%9A-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EB%88%85%EC%8A%A4-%ED%84%B0%EB%AF%B8%EB%84%90%EC%9D%84-%ED%99%94%EB%A0%A4%ED%95%98%EA%B2%8C-%F0%9F%90%A7-%EC%B5%9C%EC%8B%A0%EC%8B%9D-CLI-%EB%AA%A8%EC%9D%8C&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cAr3Bu/hyReSihjOc/62aoM5OI56vQpBcDWgdU81/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bfSXT3/hyReJS9HU3/qyEB5l9RW7aKiZpNq75TWK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/dTa9i0/hyReTO1w3W/TUtkxAebqQwaxLOaN2L9j0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/LINUX-%F0%9F%93%9A-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EB%88%85%EC%8A%A4-%ED%84%B0%EB%AF%B8%EB%84%90%EC%9D%84-%ED%99%94%EB%A0%A4%ED%95%98%EA%B2%8C-%F0%9F%90%A7-%EC%B5%9C%EC%8B%A0%EC%8B%9D-CLI-%EB%AA%A8%EC%9D%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inpa.tistory.com/entry/LINUX-%F0%9F%93%9A-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EB%88%85%EC%8A%A4-%ED%84%B0%EB%AF%B8%EB%84%90%EC%9D%84-%ED%99%94%EB%A0%A4%ED%95%98%EA%B2%8C-%F0%9F%90%A7-%EC%B5%9C%EC%8B%A0%EC%8B%9D-CLI-%EB%AA%A8%EC%9D%8C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cAr3Bu/hyReSihjOc/62aoM5OI56vQpBcDWgdU81/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bfSXT3/hyReJS9HU3/qyEB5l9RW7aKiZpNq75TWK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/dTa9i0/hyReTO1w3W/TUtkxAebqQwaxLOaN2L9j0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Modern Linux]   모던 리눅스 - 최신식 리눅스 명령어 모음&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;모던 리눅스/유닉스 명령어 대부분의 리눅스 강의나 수업에서는 초창기부터 있던 전통적인 CLI 명령어(ls, cd, pwd, cat, cp, mv, rm, mkdir, ...등) 위주로 알려준다. 그러나 이 오래된 명령어들은 작성된&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;inpa.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 블로그 내용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모르는게 훨씬 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rust 가 만들어 내는 변화인가.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;궁금해지는 언어.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소개된 프로그램 리스트&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;exa (&lt;a href=&quot;https://github.com/ogham/exa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/ogham/exa&lt;/a&gt;) - ls&lt;/li&gt;
&lt;li&gt;bat (&lt;a href=&quot;https://github.com/sharkdp/bat&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/sharkdp/bat&lt;/a&gt;) - cat&lt;/li&gt;
&lt;li&gt;fd (&lt;a href=&quot;https://github.com/sharkdp/fd&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/sharkdp/fd&lt;/a&gt;) - find&lt;/li&gt;
&lt;li&gt;ripgrep (&lt;a href=&quot;https://github.com/BurntSushi/ripgrep&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/BurntSushi/ripgrep&lt;/a&gt;) - grep&lt;/li&gt;
&lt;li&gt;delta (&lt;a href=&quot;https://github.com/dandavison/delta&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/dandavison/delta&lt;/a&gt;) - more/less/diff&lt;/li&gt;
&lt;li&gt;tldr (&lt;a href=&quot;https://github.com/tldr-pages/tldr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/tldr-pages/tldr&lt;/a&gt;) - man&lt;/li&gt;
&lt;li&gt;zoxide (&lt;a href=&quot;https://github.com/ajeetdsouza/zoxide&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/ajeetdsouza/zoxide&lt;/a&gt;) - cd&lt;/li&gt;
&lt;li&gt;Broot (&lt;a href=&quot;https://github.com/Canop/broot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/Canop/broot&lt;/a&gt;) - tree&lt;/li&gt;
&lt;li&gt;fzf (&lt;a href=&quot;https://github.com/junegunn/fzf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/junegunn/fzf&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;gtop (&lt;a href=&quot;https://github.com/aksakalli/gtop&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/aksakalli/gtop&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;bottom (&lt;a href=&quot;https://github.com/ClementTsang/bottom&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/ClementTsang/bottom&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;dust (&lt;a href=&quot;https://github.com/bootandy/dust&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/bootandy/dust&lt;/a&gt;) - du&lt;/li&gt;
&lt;li&gt;duf (&lt;a href=&quot;https://github.com/muesli/duf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/muesli/duf&lt;/a&gt;) - df&lt;/li&gt;
&lt;li&gt;procs (&lt;a href=&quot;https://github.com/dalance/procs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/dalance/procs&lt;/a&gt;) - ps&lt;/li&gt;
&lt;li&gt;gping (&lt;a href=&quot;https://github.com/orf/gping&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/orf/gping&lt;/a&gt;) - ping&lt;/li&gt;
&lt;li&gt;mcfly (&lt;a href=&quot;https://github.com/cantino/mcfly&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/cantino/mcfly&lt;/a&gt;) - history&lt;/li&gt;
&lt;li&gt;hexyl (&lt;a href=&quot;https://github.com/sharkdp/hexyl&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/sharkdp/hexyl&lt;/a&gt;) - od&lt;/li&gt;
&lt;li&gt;jq (&lt;a href=&quot;https://github.com/stedolan/jq&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/stedolan/jq&lt;/a&gt;) - sed&lt;/li&gt;
&lt;li&gt;fx (&lt;a href=&quot;https://github.com/antonmedv/fx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/antonmedv/fx&lt;/a&gt;) - sed&lt;/li&gt;
&lt;li&gt;httpie (&lt;a href=&quot;https://github.com/httpie/httpie&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/httpie/httpie&lt;/a&gt;) - curl&lt;/li&gt;
&lt;li&gt;xh (&lt;a href=&quot;https://github.com/ducaale/xh&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/ducaale/xh&lt;/a&gt;) - curl&lt;/li&gt;
&lt;li&gt;dog (&lt;a href=&quot;https://github.com/ogham/dog&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/ogham/dog&lt;/a&gt;) - dig&lt;/li&gt;
&lt;li&gt;nnn (&lt;a href=&quot;https://github.com/jarun/nnn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/jarun/nnn&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fzf + fd + vim plugin 은 필수조합...&lt;/p&gt;</description>
      <category>Interesthing</category>
      <category>FD</category>
      <category>FZF</category>
      <category>Linux</category>
      <author>iosroid</author>
      <guid isPermaLink="true">https://iosroid.tistory.com/125</guid>
      <comments>https://iosroid.tistory.com/125#entry125comment</comments>
      <pubDate>Tue, 10 Jan 2023 19:00:39 +0900</pubDate>
    </item>
  </channel>
</rss>