LINUX.ORG.RU

История изменений

Исправление DarkEld3r, (текущая версия) :

Ты хочешь параметризовать дженерик объектом? В Rust это невозможно.

Во первых, не совсем понимаю, что значит «параметризовать дженерик объектом».

struct O {}
struct G<T = O> { ... }
Разве вот это не оно?

Во вторых, мне, в первую очередь, хотелось «параметризовать поведение» и не хранить в объекте лишнего, если это возможно. И это возможно, даже без impl trait:

trait Validator<Data> {
    fn validate(_: &Data) -> bool;
}

struct DefaultValidator {}

impl<Data> Validator<Data> for DefaultValidator {
    fn validate(_: &Data) -> bool {
        false
    }
}

impl Default for DefaultValidator {
    fn default() -> Self {
        DefaultValidator {}
    }
}

struct Container<Data, V: Validator<Data> + Default = DefaultValidator> {
    data: Vec<Data>,
    validator: V,
}

impl<Data> Container<Data, DefaultValidator> {
    fn new() -> Self {
        Container {
            data: Vec::new(),
            validator: DefaultValidator::default(),
        }
    }
}
Благодаря тому, что пустые объекты в расте занимают нулевой объём, размер контейнера не увеличится. Получается даже гибче чем в плюсах, где можно или указателем на функцию параметризировать, но тогда объект уже не подсунуть или хранить std::function, но тогда размер объекта будет больше, даже если ничего хранить не надо.

Можно даже мою изначальную хотелку с подсовыванием функции сделать, если реализовать Fn для Validator.

И «бонусный вопрос»: может в курсе почему impl trait решили делать именно в таком виде? Разве не было бы логичнее делать аналогично с входными параметрами?

fn foo(Input: SomeTrait, Output: SomeOtherTrait)(val: &Input) -> Output { ... }

Исправление DarkEld3r, :

Ты хочешь параметризовать дженерик объектом? В Rust это невозможно.

Во первых, не совсем понимаю, что значит «параметризовать дженерик объектом».

struct O {}
struct G<T = O> { ... }
Разве вот это не оно?

Во вторых, мне, в первую очередь, хотелось «параметризовать поведение» и не хранить в объекте лишнего, если это возможно. И это возможно, даже без impl trait:

trait Validator<Data> {
    fn validate(_: &Data) -> bool;
}

struct DefaultValidator {}

impl<Data> Validator<Data> for DefaultValidator {
    fn validate(_: &Data) -> bool {
        false
    }
}

impl Default for DefaultValidator {
    fn default() -> Self {
        DefaultValidator {}
    }
}

struct Container<Data, V: Validator<Data> + Default = DefaultValidator> {
    data: Vec<Data>,
    validator: V,
}

impl<Data> Container<Data, DefaultValidator> {
    fn new() -> Self {
        Container {
            data: Vec::new(),
            validator: DefaultValidator::default(),
        }
    }
}
Благодаря тому, что пустые объекты в расте занимают нулевой объём, размер контейнера не увеличится.

Можно даже мою изначальную хотелку с подсовыванием функции сделать, если реализовать Fn для Validator.

И «бонусный вопрос»: может в курсе почему impl trait решили делать именно в таком виде? Разве не было бы логичнее делать аналогично с входными параметрами?

fn foo(Input: SomeTrait, Output: SomeOtherTrait)(val: &Input) -> Output { ... }

Исходная версия DarkEld3r, :

Ты хочешь параметризовать дженерик объектом? В Rust это невозможно.

Во первых, не совсем понимаю, что значит «параметризовать дженерик объектом».

struct O {}
struct G<T = O> { ... }
Разве вот это не оно?

Во вторых, мне, в первую очередь, хотелось «параметризовать поведение» и не хранить в объекте лишнего, если это возможно. И это возможно, даже без impl trait:

trait Validator<Data> {
    fn validate(_: &Data) -> bool;
}

struct DefaultValidator {}

impl<Data> Validator<Data> for DefaultValidator {
    fn validate(_: &Data) -> bool {
        false
    }
}

impl Default for DefaultValidator {
    fn default() -> Self {
        DefaultValidator {}
    }
}

struct Container<Data, V: Validator<Data> + Default = DefaultValidator> {
    data: Vec<Data>,
    validator: V,
}

impl<Data> Container<Data, DefaultValidator> {
    fn new() -> Self {
        Container {
            data: Vec::new(),
            validator: DefaultValidator::default(),
        }
    }
}
Можно даже мою изначальную хотелку с подсовыванием функции сделать, если реализовать Fn для Validator.

И «бонусный вопрос»: может в курсе почему impl trait решили делать именно в таком виде? Разве не было бы логичнее делать аналогично с входными параметрами?

fn foo(Input: SomeTrait, Output: SomeOtherTrait)(val: &Input) -> Output { ... }