4795 words
24 minutes
260106_traits01
2026-01-06

link#







Rust가 추구하는 목표는 C++목표와 동일하다.#

  • C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for [Stroustrup, 1994]. And further: What you do use, you couldn’t hand code any better.
  • C++ 구현은 제로 오버헤드 원칙을 따릅니다: 사용하지 않는 것은 비용을 지불하지 않는 것입니다 [Strustrup, 1994]. 그리고 더 나아가: 사용하는 것은 핸드 코딩보다 더 나은 방법이 없습니다.
    • Stroustrup
    • C++ 프로그래밍 언어의 창시자는 비야네 스트롭스트룹(Bjarne Stroustrup)

(Rust Traits의 최대 장점..zero size로도 구현 가능)Abstraction without overhead: traits in Rust|🔝|#

Traits Summary|🔝|#

  • Traits define abstract behavior that can be utilzed by multiple types
  • We can define function argument types with a trait
  • We can use traits to constrain function arguments
  • We can constrain return types using traits
  • We can conditionally create types on the heap at runtime using trait objects.
  • We can use traits to conditionally implement methods

  • Traits define abstract behavior that can be utilzed by multiple types
Traits = define abstract behavior
do를 의미
특성은 여러 유형에 의해 활용될 있는 추상적 행동을 정의한다.

  • We can define function argument types with a trait
    • 특성(trait)으로 함수 인수 유형을 정의할 수 있습니다.

  • We can use traits to constrain function arguments
    • 우리는 함수 인수를 제한하기 위해 특성을 사용할 수 있다

  • We can constrain return types using traits
    • 우리는 특성을 사용하여 반환 유형을 제한할 수 있습니다.

  • We can conditionally create types on the heap at runtime using trait objects.
    • 특성 객체(trait object)를 사용하여 런타임(runtime)에 힙(heap)에 조건부로 유형(conditionally create types) 을 만들 수 있습니다.

  • We can use traits to conditionally implement methods
    • 우리는 조건부로 방법을 구현하기 위해 특성을 사용할 수 있다.


std Trait는 무조건 외워야함(Debug, Display, Eq, PartialEq, From .. 그 외에 은근히 많다.)#

  • From은 유용하게 쓰인다. Traits 마지막 시간에 할 예정.

  • DebugDisplay 는 거의 동일하기

    • Debug{:?} 이런 패턴
    • Display{} 이런 패턴
use std::fmt::{self, Debug};

struct Data01 {
    data: i32,
    data2: f32,
}

impl Debug for Data01 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} \n {} \n \ndebugging address~~\ndata: memory address : {:p}\ndata2: memory address : {:p}",
            self.data, self.data2, &self.data, &self.data2
        )
    }
}

fn main() {
    let my_data = Data01 {
        data: 20,
        data2: 100.0,
    };

    println!("my_ data : {my_data:?}");
}

pretzelhammer/rust-blog#

https://github.com/pretzelhammer/rust-blog

pretzelhammer Tutorial(Traits)#


traits여기 좋은거 많다.#

https://github.com/rust-lang/rfcs/blob/master/text/0048-traits.md


Object Safety(Traits)#

https://doc.rust-lang.org/reference/items/traits.html#object-safety

Traits Summary#

  • Traits
  • Traits define abstract behavior that can be utilzed by multiple types
  • We can define function argument types with a trait
  • We can use traits to constrain function arguments
  • We can constrain return types using traits
  • We can conditionally create types on the heap at runtime using trait objects.
  • We can use traits to conditionally implement methods
  • 특성
  • 특성은 여러 유형이 활용할 수 있는 추상적인 행동을 정의합니다
  • 우리는 특성을 가진 함수 인수 유형을 정의할 수 있습니다
  • 특성을 사용하여 함수 인수를 제한할 수 있습니다
  • 특성을 사용하여 반품 유형을 제한할 수 있습니다
  • 런타임 시 특성 객체를 사용하여 힙에 타입을 조건부로 생성할 수 있습니다.
  • 특성을 사용하여 조건부로 방법을 구현할 수 있습니다

⏺ Created traits_summary.rs with 12 Rust trait examples that compile successfully:#

  1. Basic Trait Definition - Simple Speak trait with Dog and Cat implementations
  2. Trait as Function Argument - Drawable trait with render(&impl Drawable) function
  3. Trait Bounds - Comparable trait with find_max<T: Comparable>() constraining arguments
  4. Return Type with Trait - Returns Box<dyn Animal> trait object for runtime polymorphism
  5. Trait Objects - Box<dyn Noise> for dynamic dispatch with heterogeneous collections
  6. Conditional Methods - impl<T: Display> provides print_all() only when T: Display
  7. Default Implementations - Greeter trait with default methods that can be overridden
  8. Supertraits - trait ElectricCar: Vehicle demonstrates trait inheritance
  9. Derive Traits - #[derive(Debug, Clone, PartialEq, Eq)] on Book struct
  10. Associated Types - trait Iterator2 { type Item } with Counter implementation
  11. Generic Traits - trait Add<Rhs = Self> with type parameters and Output associated type
  12. Trait Objects with Lifetime - create_messenger() returns Box<dyn Messenger> for runtime selection

    1. 기본 특성 정의 - 개와 고양이가 구현된 간단한 말하기 특성
    1. 함수 인수로서의 특성 - 렌더(&impl 드로잉 가능) 함수를 사용하여 그릴 수 있는 특성
    1. 특성 경계 - find_max<T: Comparable>() 제약 인수와 비교 가능한 특성
    1. 특성이 있는 반환 유형 - 런타임 다형성을 위한 박스<다인 동물> 특성 객체 반환
    1. 형질 객체 - 이질적인 컬렉션을 사용한 동적 디스패치를 위한 박스<다인 노이즈>
    1. 조건부 방법 - impl<T: Display>T: Display일 때만 print_all()을 제공합니다
    1. 기본 구현 - 무시할 수 있는 기본 메서드가 있는 그리터 특성
    1. 슈퍼 특성 - 특성 전기 자동차: 특성 유전을 보여주는 차량
    1. 책 구조에서 특성 도출 - #[디버그, 클론, 부분 방정식(derives(Debug, Clone, PartialEq, Eq))
    1. 관련 유형 - 카운터 구현을 포함한 특성 반복자2 {유형 항목}
    1. 일반적인 특성 - 유형 매개변수와 출력 관련 유형을 가진 trait 추가<Rhs = Self>
    1. 수명이 있는 특성 객체 - create_messenger()는 런타임 선택을 위해 Box<dyn Messenger>를 반환합니다
// ========================================
// Example 01: Basic Trait Definition & Implementation
// ========================================
trait Speak {
    fn speak(&self) -> String;
}

struct Dog;
struct Cat;

impl Speak for Dog {
    fn speak(&self) -> String {
        String::from("Woof!")
    }
}

impl Speak for Cat {
    fn speak(&self) -> String {
        String::from("Meow!")
    }
}

fn example_01_basic_trait() {
    let dog = Dog;
    let cat = Cat;

    println!("Dog says: {}", dog.speak());
    println!("Cat says: {}", cat.speak());
    println!();
}

// ========================================
// Example 02: Trait as Function Argument
// ========================================
trait Drawable {
    fn draw(&self) -> String;
}

struct Circle {
    radius: f64,
}
struct Square {
    side: f64,
}

impl Drawable for Circle {
    fn draw(&self) -> String {
        format!("Drawing a circle with radius {}", self.radius)
    }
}

impl Drawable for Square {
    fn draw(&self) -> String {
        format!("Drawing a square with side {}", self.side)
    }
}

// Function accepting any type that implements Drawable
fn render(shape: &impl Drawable) {
    println!("{}", shape.draw());
}

fn example_02_trait_as_argument() {
    println!("--- Example 02: Trait as Function Argument ---");

    let circle = Circle { radius: 5.0 };
    let square = Square { side: 10.0 };

    render(&circle);
    render(&square);
    println!();
}

// ========================================
// Example 03: Trait Bounds (Constraining Arguments)
// ========================================
trait Comparable {
    fn compare(&self, other: &Self) -> std::cmp::Ordering;
}

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl Comparable for Point {
    fn compare(&self, other: &Self) -> std::cmp::Ordering {
        let self_mag = self.x * self.x + self.y * self.y;
        let other_mag = other.x * other.x + other.y * other.y;
        self_mag.cmp(&other_mag)
    }
}

// Using trait bounds with where clause
fn find_max<T: Comparable>(items: &[T]) -> Option<&T> {
    if items.is_empty() {
        return None;
    }
    let mut max = &items[0];
    for item in &items[1..] {
        if item.compare(max).is_gt() {
            max = item;
        }
    }
    Some(max)
}

fn example_03_trait_bounds() {
    println!("--- Example 03: Trait Bounds ---");

    let points = vec![
        Point { x: 1, y: 2 },
        Point { x: 3, y: 4 },
        Point { x: 0, y: 1 },
    ];

    if let Some(max_point) = find_max(&points) {
        println!("The point with largest magnitude: {:?}", max_point);
    }
    println!();
}

// ========================================
// Example 04: Return Type with Trait
// ========================================
trait Animal {
    fn name(&self) -> &str;
}

struct Lion;
struct Tiger;

impl Animal for Lion {
    fn name(&self) -> &str {
        "Lion"
    }
}

impl Animal for Tiger {
    fn name(&self) -> &str {
        "Tiger"
    }
}

// Function returning a trait object (can return different types at runtime)
fn create_big_cat(is_lion: bool) -> Box<dyn Animal> {
    if is_lion {
        Box::new(Lion)
    } else {
        Box::new(Tiger)
    }
}

fn example_04_return_type_with_trait() {
    println!("--- Example 04: Return Type with Trait ---");

    let cat1 = create_big_cat(true);
    let cat2 = create_big_cat(false);

    println!("Created: {}", cat1.name());
    println!("Created: {}", cat2.name());
    println!();
}

// ========================================
// Example 05: Trait Objects (Dynamic Dispatch)
// ========================================
trait Noise {
    fn make_noise(&self);
}

struct DogToy;
struct CatToy;
struct BirdToy;

impl Noise for DogToy {
    fn make_noise(&self) {
        println!("*bark bark*");
    }
}

impl Noise for CatToy {
    fn make_noise(&self) {
        println!("*meow meow*");
    }
}

impl Noise for BirdToy {
    fn make_noise(&self) {
        println!("*tweet tweet*");
    }
}

// Trait objects allow runtime polymorphism
fn play_with_all(toys: &[Box<dyn Noise>]) {
    println!("Playing with {} toys:", toys.len());
    for toy in toys {
        toy.make_noise();
    }
}

fn example_05_trait_objects() {
    println!("--- Example 05: Trait Objects ---");

    let toys: Vec<Box<dyn Noise>> = vec![Box::new(DogToy), Box::new(CatToy), Box::new(BirdToy)];

    play_with_all(&toys);
    println!();
}

// ========================================
// Example 06: Conditional Methods (where clause)
// ========================================
trait Container {
    type Item;

    fn get(&self, index: usize) -> Option<&Self::Item>;
    fn len(&self) -> usize;
}

struct MyVec<T> {
    items: Vec<T>,
}

impl<T> MyVec<T> {
    fn new() -> Self {
        MyVec { items: Vec::new() }
    }

    fn push(&mut self, item: T) {
        self.items.push(item);
    }
}

impl<T> Container for MyVec<T> {
    type Item = T;

    fn get(&self, index: usize) -> Option<&T> {
        self.items.get(index)
    }

    fn len(&self) -> usize {
        self.items.len()
    }
}

// Conditional method: only implemented when T implements Display
impl<T: std::fmt::Display> MyVec<T> {
    fn print_all(&self) {
        println!("Container contents:");
        for (i, item) in self.items.iter().enumerate() {
            println!("  [{}]: {}", i, item);
        }
    }
}

fn example_06_conditional_methods() {
    println!("--- Example 06: Conditional Methods ---");

    let mut vec1 = MyVec::new();
    vec1.push("Hello");
    vec1.push("World");
    vec1.print_all(); // Available because &str implements Display

    println!();
}

// ========================================
// Example 07: Default Implementations
// ========================================
trait Greeter {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }

    fn farewell(&self) -> String {
        String::from("Goodbye!")
    }
}

struct Person;
struct Robot;

impl Greeter for Person {
    fn greet(&self) -> String {
        String::from("Hi, nice to meet you!")
    }
    // farewell uses default implementation
}

impl Greeter for Robot {
    // Both greet and farewell use default implementations
}

fn example_07_default_implementations() {
    println!("--- Example 07: Default Implementations ---");

    let person = Person;
    let robot = Robot;

    println!("Person: {}", person.greet());
    println!("Person: {}", person.farewell());
    println!("Robot: {}", robot.greet());
    println!("Robot: {}", robot.farewell());
    println!();
}

// ========================================
// Example 08: Supertraits (Trait Inheritance)
// ========================================
trait Vehicle {
    fn start(&self) -> String {
        String::from("Vehicle starting...")
    }
}

// ElectricCar "inherits" from Vehicle
trait ElectricCar: Vehicle {
    fn charge(&self) -> String;
}

struct Tesla;

impl Vehicle for Tesla {
    fn start(&self) -> String {
        String::from("Tesla starting silently...")
    }
}

impl ElectricCar for Tesla {
    fn charge(&self) -> String {
        String::from("Charging at Supercharger...")
    }
}

fn example_08_supertraits() {
    println!("--- Example 08: Supertraits ---");

    let tesla = Tesla;
    println!("{}", tesla.start());
    println!("{}", tesla.charge());
    println!();
}

// ========================================
// Example 09: Derive Macros (Standard Library Traits)
// ========================================
#[derive(Debug, Clone, PartialEq, Eq)]
struct Book {
    title: String,
    author: String,
    pages: u32,
}

fn example_09_derive_traits() {
    println!("--- Example 09: Derive Traits ---");

    let book1 = Book {
        title: String::from("The Rust Book"),
        author: String::from("Steve Klabnik"),
        pages: 500,
    };

    // Debug: {:?}
    println!("{:?}", book1);

    // Clone
    let book2 = book1.clone();
    println!("Cloned: {:?}", book2);

    // PartialEq
    let book3 = Book {
        title: String::from("The Rust Book"),
        author: String::from("Steve Klabnik"),
        pages: 500,
    };
    println!("book1 == book3: {}", book1 == book3);
    println!();
}

// ========================================
// Example 10: Associated Types
// ========================================
trait Iterator2 {
    type Item;

    fn next(&mut self) -> Option<Self::Item>;
}

struct Counter {
    current: u32,
    max: u32,
}

impl Counter {
    fn new(max: u32) -> Self {
        Counter { current: 0, max }
    }
}

impl Iterator2 for Counter {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current < self.max {
            let val = self.current;
            self.current += 1;
            Some(val)
        } else {
            None
        }
    }
}

fn example_10_associated_types() {
    println!("--- Example 10: Associated Types ---");

    let mut counter = Counter::new(5);
    while let Some(val) = counter.next() {
        println!("Count: {}", val);
    }
    println!();
}

// ========================================
// Example 11: Generic Traits with Type Parameters
// ========================================
trait Add<Rhs = Self> {
    type Output;

    fn add(self, rhs: Rhs) -> Self::Output;
}

#[derive(Debug, Clone, Copy)]
struct Meter(f64);
#[derive(Debug, Clone, Copy)]
struct Foot(f64);

impl Add for Meter {
    type Output = Meter;

    fn add(self, rhs: Self) -> Self::Output {
        Meter(self.0 + rhs.0)
    }
}

impl Add<Meter> for Foot {
    type Output = Meter;

    fn add(self, rhs: Meter) -> Meter {
        Meter(self.0 * 0.3048 + rhs.0)
    }
}

fn example_11_generic_traits() {
    println!("--- Example 11: Generic Traits ---");

    let m1 = Meter(10.0);
    let m2 = Meter(5.0);
    let m3 = m1.add(m2);
    println!("Meter + Meter = {:?}", m3);

    let f = Foot(10.0);
    let m = Meter(5.0);
    let result = f.add(m);
    println!("Foot + Meter = {:?}", result);
    println!();
}

// ========================================
// Example 12: Trait Object with Lifetime
// ========================================
trait Messenger {
    fn send(&self, msg: &str);
}

struct EmailMessenger;
struct SmsMessenger;

impl Messenger for EmailMessenger {
    fn send(&self, msg: &str) {
        println!("Sending email: {}", msg);
    }
}

impl Messenger for SmsMessenger {
    fn send(&self, msg: &str) {
        println!("Sending SMS: {}", msg);
    }
}

// Return a trait object with lifetime
fn create_messenger(use_email: bool) -> Box<dyn Messenger> {
    if use_email {
        Box::new(EmailMessenger)
    } else {
        Box::new(SmsMessenger)
    }
}

fn notify_all(messengers: &[Box<dyn Messenger>], message: &str) {
    println!("Notifying via {} messengers:", messengers.len());
    for messenger in messengers {
        messenger.send(message);
    }
}

fn example_12_trait_object_lifetime() {
    println!("--- Example 12: Trait Objects with Lifetime ---");

    let m1 = create_messenger(true);
    let m2 = create_messenger(false);
    let messengers = vec![m1, m2];

    notify_all(&messengers, "Hello, World!");
    println!();
}

fn main() {
    println!("=== 12 Rust Traits Examples ===\n");

    example_01_basic_trait();
    example_02_trait_as_argument();
    example_03_trait_bounds();
    example_04_return_type_with_trait();
    example_05_trait_objects();
    example_06_conditional_methods();
    example_07_default_implementations();
    example_08_supertraits();
    example_09_derive_traits();
    example_10_associated_types();
    example_11_generic_traits();
    example_12_trait_object_lifetime();
}

Result#

=== 12 Rust Traits Examples ===

Dog says: Woof!
Cat says: Meow!

--- Example 02: Trait as Function Argument ---
Drawing a circle with radius 5
Drawing a square with side 10

--- Example 03: Trait Bounds ---
The point with largest magnitude: Point { x: 3, y: 4 }

--- Example 04: Return Type with Trait ---
Created: Lion
Created: Tiger

--- Example 05: Trait Objects ---
Playing with 3 toys:
*bark bark*
*meow meow*
*tweet tweet*

--- Example 06: Conditional Methods ---
Container contents:
  [0]: Hello
  [1]: World

--- Example 07: Default Implementations ---
Person: Hi, nice to meet you!
Person: Goodbye!
Robot: Hello there!
Robot: Goodbye!

--- Example 08: Supertraits ---
Tesla starting silently...
Charging at Supercharger...

--- Example 09: Derive Traits ---
Book { title: "The Rust Book", author: "Steve Klabnik", pages: 500 }
Cloned: Book { title: "The Rust Book", author: "Steve Klabnik", pages: 500 }
book1 == book3: true

--- Example 10: Associated Types ---
Count: 0
Count: 1
Count: 2
Count: 3
Count: 4

--- Example 11: Generic Traits ---
Meter + Meter = Meter(15.0)
Foot + Meter = Meter(8.048)

--- Example 12: Trait Objects with Lifetime ---
Notifying via 2 messengers:
Sending email: Hello, World!
Sending SMS: Hello, World!

Iterable trait|🔝|#

trait Iterable {
    type A;
    type I<'a>: Iterator<&'a Self::A>;

    fn iter(&self) -> Self::I<'_>;
}

trait IterableMut {
    type A;
    type I<'a>: Iterator<&'a mut Self::A>;

    fn iter_mut(&self) -> Self::I<'_>;
}

Foreign Types and Traits|🔝|#

001


Traits공부하다가 Coherence개념 나옴|🔝|#

Coherence#

Traits Prototype(JavaScript임)|🔝|#


  • 01

Traits and trait objects - more than just interfaces - Rust Community Stuttgart | Max Bruckner|🔝|#

Agenda#

  • What is a trait?
  • Orphan rule
  • Generics
    • Trait bounds
    • Generic types
  • Trait Objects
    • Memory layout
    • Object safety rules
  • Generic traits
  • Associated types

What is a trait?|🔝|#

  • Interface?
  • Type class?
  • Collection of methods?
  • Shared behavior

dyn is a prefix of a trait object’s type.|🔝|#

Dynamically Sized Types(DST)#

  • Pointer types to DSTs are sized but have twice the size of pointers to sized types
    • Pointers to slices also store the number of elements of the slice.
    • Pointers to trait objects also store a pointer to a vtable.
  • DSTs can be provided as type arguments to generic type parameters having the special ?Sized bound. They can also be used for associated type definitions when the corresponding associated type declaration has a ?Sized bound. By default, any type parameter or associated type has a Sized bound, unless it is relaxed using ?Sized.
  • Traits may be implemented for DSTs. Unlike with generic type parameters, Self: ?Sized is the default in trait definitions.
  • Structs may contain a DST as the last field; this makes the struct itself a DST.

  • 포인터 유형 - DST는 크기는 작지만 크기 유형에 대한 포인터 크기는 2배입니다

    • 슬라이스에 대한 포인터는 슬라이스의 요소 수도 저장합니다.
    • 특성 개체에 대한 포인터는 vtable에 대한 포인터도 저장합니다.
  • DST는 특수한 ?Size 바운드를 갖는 일반적인 유형 매개 변수에 대한 유형 인수로 제공될 수 있습니다. 해당 유형 선언에 ?Size 바운드가 있는 경우 관련 유형 정의에도 사용할 수 있습니다. 기본적으로 모든 유형 매개 변수 또는 관련 유형은 ?Size를 사용하여 완화되지 않는 한 Size 바운드가 있습니다.

  • 특성은 DST에 대해 구현될 수 있습니다. 일반적인 유형 매개변수와 달리 Self:?Size가 특성 정의의 기본값입니다.

  • 구조물은 마지막 필드로 DST를 포함할 수 있습니다. 그러면 구조물 자체가 DST가 됩니다.

  • https://doc.rust-lang.org/reference/dynamically-sized-types.html

  • An example of a trait object:

trait Printable {
    fn stringify(&self) -> String;
}

impl Printable for i32 {
    fn stringify(&self) -> String { self.to_string() }
}

fn print(a: Box<dyn Printable>) {
    println!("{}", a.stringify());
}

fn main() {
    print(Box::new(10) as Box<dyn Printable>);
}

Easy Rust 132: Boxes in dynamic dispatch vs impl trait | mithradates#



Marker Traits|🔝|#

  • Traits without methods tec. just for use in bounds

    • 단지 경계에서 사용하기 위한 방법 등이 없는 특성
  • Marks types that can be transfered across thread boundaries.

    • 스레드 경계 간에 전송되는 유형을 표시합니다.
unsafe trait Send {}
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
    F: FnOnce() -> T + Send + 'static,
    T: Send + 'static,
  • Send bound ensures no thread unsafe type can be passed to another thread.
    • 보내기 바운드는 다른 스레드에 안전하지 않은 유형을 전달할 수 없도록 합니다.
  • Rc
let rc = Rc::new(1);
std::thread::spawn(|| println!("{}", rc));

  • 01-part2

Rust Linz, July 2021 - Rainer Stropek - Traits, not your grandparents’ interfaces | Rust|🔝|#


  • 02

AsRef/Borrow Traits, and the ?Sized Marker - Rust [Video Request] | danlogs|🔝|#


  • 03

Abstraction without overhead: traits in Rust|🔝|#


  • 04

Object Safety|🔝|#


  • 05

Rust Does Interfaces BETTER! | Trusty Bits|🔝|#


  • 06

Rust Powered Polymorphism ⚡️ With Traits | Code to the Moon|🔝|#


  • 07

5 traits your Rust types must implement | Let’s Get Rusty|🔝|#


  • 08

Two Ways To Do Dynamic Dispatch | Logan Smith|🔝|#

wide pointerpointer to intrusive
intrusivenoyes
stack size2 ptrs1 ptr
indirections23
memory
cost paid
only for
dynamic pointers
for all objects

Dynamic vs Static Dispatch in Rust | Ryan Levick|🔝|#


  • 09

Highter-Ranked Trait Bounds|🔝|#


  • 10

아무래도 요즘 쓰는 dyn 키워드가 과거에는 ~ (옛날문법) tilde였던거 같다|🔝|#


  • 11

Using Trait Objects in Rust | Let’s Get Rusty|🔝|#


  • 12

Hands-on With Dynamic Dispatch Traits in Rust 🦀 Rust Tutorial for Developers | Trevor Sullivan|🔝|#


  • 13

C++ vs Rust - Impl vs Dyn - Arm vs x86 | Sonia Kolasinska|🔝|#


dyn Trait vs impl Trait#

  • 이 글이 젤 맘에 듬

  • https://internals.rust-lang.org/t/what-is-the-difference-between-impl-trait-and-dyn-trait/8823/13

    • dyn Trait is a concert type,
      • and can be used in any places that you need a concert type (However, it is unsized, and in many places there is an implicit Sized bound, so not quite everywhere). Under the hook, it contains a vtable of a type implements Trait, and something that let the compiler refer to the type underneath.
        • dyn Trait은 콘서트 유형으로 콘서트 유형이 필요한 모든 곳에서 사용할 수 있습니다(그러나 크기가 크지 않고 많은 곳에서 암묵적인 크기 제한이 있으므로 모든 곳에서 사용할 수는 없습니다). 후크 아래에는 Trait을 구현하는 유형의 vtable이 포함되어 있으며, 컴파일러가 그 아래 유형을 참조할 수 있는 기능이 있습니다.
    • impl Trait is an anonymous type.
      • It is a type that you cannot name, which means any two impl Trait occurrences represents different types. A proved RFC proposed to allow using it in a type alias statements so it maybe aliased.
        • impl Trait은 익명의 유형입니다. 이름을 지정할 수 없는 유형이므로 두 번의 impl Trait 발생은 서로 다른 유형을 나타냅니다. 증명된 RFC는 앨리어싱될 수 있도록 유형 가명 문에 사용할 수 있도록 제안했습니다.
  • In argument position, impl Trait allows the caller pass on any single type that implements Trait. In the return position, impl Trait allows the callee returns any single type that implements Trait. In any case, this type cannot be referred to in any further contexts, and it is always the value creator to pick up a type.

    • 인수 위치에서 impl Trait은 발신자가 Trait을 구현하는 모든 단일 유형을 전달할 수 있도록 허용합니다. 반환 위치에서 impl Trait은 발신자가 Trait을 구현하는 모든 단일 유형을 반환할 수 있도록 허용합니다. 어쨌든 이 유형은 더 이상의 맥락에서 참조할 수 없으며, 유형을 선택하는 것은 항상 가치 생성자입니다.

rfc 34511문서 참고 & 같이보면 좋은글#

RPIT (return-position impl Trait) and APIT (argument-position impl Trait)#

  • https://varkor.github.io/blog/2018/07/03/existential-types-in-rust.html

  • …Which means we now have a distinction between the two.

    • Though argument-position and return-position impl Trait are both forms of existential quantification,
      • they’re over different scopes: APIT is tightly-bound,
      • whereas RPIT is bound at the level of the whole function.
  • …이는 이제 두 가지를 구분할 수 있다는 것을 의미합니다. 인수 위치와 반환 위치는 모두 실존적 정량화의 한 형태이지만, 서로 다른 범위에 걸쳐 있습니다

    • APIT은 긴밀하게 결합되어 있는 반면,
    • RPIT는 전체 함수의 수준에서 결합되어 있습니다.

하스켈에서 나오는 Existential Type 개념#

260106_traits01
https://younghakim7.github.io/blog/posts/260106_traits01/
Author
YoungHa
Published at
2026-01-06