标签: trait-objects

为什么不能将&&(Sized + Trait)强制转换为&dyn Trait?

在下面的代码中,不可能从对实现相同特征的动态大小类型的引用中获得对特征对象的引用。为什么会这样呢?究竟是什么区别&dyn Trait&(?Sized + Trait)我是否可以使用这两种调用方法特质?

实现的类型FooTraitContainerTrait可能例如具有type Contained = dyn FooTraittype Contained = T在哪里T实现的具体类型FooTrait。在这两种情况下,都很难获得&dyn FooTrait。我想不出另一种情况,这是行不通的。为什么在通用情况下这不可能FooTraitContainerTrait

trait FooTrait {
    fn foo(&self) -> f64;
}

///

trait FooTraitContainerTrait {
    type Contained: ?Sized + FooTrait;
    fn get_ref(&self) -> &Self::Contained;
}

///

fn foo_dyn(dyn_some_foo: &dyn FooTrait) -> f64 {
    dyn_some_foo.foo()
}

fn foo_generic<T: ?Sized + FooTrait>(some_foo: &T) -> f64 {
    some_foo.foo()
}

///

fn foo_on_container<C: FooTraitContainerTrait>(containing_a_foo: &C) -> …
Run Code Online (Sandbox Code Playgroud)

generics polymorphism rust trait-objects

5
推荐指数
1
解决办法
168
查看次数

获取子类型上的 Rc&lt;RefCell&lt;dyn T&gt;&gt;&gt;

我有以下定义:

trait A {
    fn f(&self);
}

trait B: A {
// ...
}
Run Code Online (Sandbox Code Playgroud)

我想实现这样的功能:

fn convert(v: Rc<RefCell<dyn B>>) -> Rc<RefCell<dyn A>> {
}
Run Code Online (Sandbox Code Playgroud)

我想要一种方法来返回共享同一对象的值,这意味着使用这些声明:

let x: Rc<RefCell<dyn B>> /* = ... */;
let y = convert(Rc::clone(&x));
Run Code Online (Sandbox Code Playgroud)

调用x.f()y.f()应用调用位于同一对象上。

我如何实现该函数convert或如何更改类型定义以具有该行为和该类型的转换(到子对象的转换)。

rust subtyping trait-objects

5
推荐指数
1
解决办法
1122
查看次数

具有 Box 字段并隐含异步特征的 Rust 结构

我遇到了具有 Box 字段并隐含异步特征的结构的问题。具体来说

error: future cannot be sent between threads safely
Run Code Online (Sandbox Code Playgroud)

看起来发生错误是因为我在 impl 是异步特征的结构中使用了 Box 字段。

以下是我想要完成的任务和遇到的问题的一个最小示例。你可以在这里找到它的游乐场。

error: future cannot be sent between threads safely
Run Code Online (Sandbox Code Playgroud)

首先,我该如何解决这个问题?

其次,我本质上是在尝试为结构编写特征,以便实现的结构可以轻松地与其他结构交换,类似于我在 Java 中为对象编写接口的方式。我意识到这可能不是我应该考虑 Rust 组件设计的方式,但我是一个初学者,不确定什么是基于特征的设计的正确方法。如果这不是惯用的 Rust,您将如何重新设计它,以便它仍然实现设计目标(在堆栈上下创建和使用特征以允许轻松的 impl 交换)?

谢谢。

oop traits rust async-await trait-objects

5
推荐指数
1
解决办法
1779
查看次数

在 Rust 中克隆一个 Rc 指针到一个特征对象上?

我正在学习 Rust,不明白为什么以下内容不起作用。我想我们无法在特征对象上克隆 Rc 指针?我如何将这样的引用传递给仅由特征定义的函数,如尝试的那样some_function

use std::rc::Rc;

trait SomeTrait {}
struct SomeThing {}
impl SomeTrait for SomeThing {}

fn some_function(s: Rc<dyn SomeTrait>) {}
fn another_function(s: &Rc<dyn SomeTrait>) {}

fn main() {
    let s = Rc::new(SomeThing{});

    // This doesnt work
    some_function(Rc::clone(&s));

    // I could do this
    some_function(s);

    // But then I could not do this
    some_function(s);
    
    // For that matter, neither can I do this
    another_function(&s);
}
Run Code Online (Sandbox Code Playgroud)

smart-pointers traits rust trait-objects

5
推荐指数
1
解决办法
554
查看次数

预期特征对象“dyn Responsability”,找到类型参数“T”

我正在尝试在 Rust 中实现一个责任链:

链接到游乐场

use std::error::Error;

struct Query {
    query: String,
}

struct Response {
    response: u64,
}

trait Responsability {
    fn take(&self, iterator: std::slice::Iter<Box<dyn Responsability>>, query: Query) -> Result<Response, Box<dyn Error>>;
}

struct ResponsabilityChain<T: Responsability> {
    responsabilities: Vec<Box<T>>,
}

impl<T: Responsability> ResponsabilityChain<T>
where
    T: Responsability,
{
    pub fn new(responsabilities: Vec<T>) -> Self {
        let responsabilities = responsabilities.into_iter()
            .map(|elt| Box::new(elt))
            .collect();
        
        Self { responsabilities }
    }
    
    pub fn launch(&self, query: Query) -> Result<Response, Box<dyn Error>> {
        let iterator = self.responsabilities.iter(); …
Run Code Online (Sandbox Code Playgroud)

rust trait-objects

5
推荐指数
1
解决办法
3124
查看次数

如何实现 T where T: Foo OR Bar 的特征

在 Rust 中,您可以为任何实现其他特征组合的类型自动实现特征。IE:

impl<T: Foo + Bar> SomeTrait for T {
    some_function(&self) {
        /*...*/
    }
}
Run Code Online (Sandbox Code Playgroud)

我想做的是定义一种关系,其中和 都Foo足以Bar自行实现。基本上是这样的:SomeTrait

impl<T: Foo> SomeTrait for T {
    some_function(&self) {
        /*...*/
    }
}

impl<T: Bar> SomeTrait for T {
    some_function(&self) {
        /*...*/
    }
}
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为您要实现SomeTrait两次T,并且编译器不可能知道在 where 的情况下要做什么T: Foo + Bar,但能够做到这一点真是太好了。

有没有某种方法可以“抽象”解决这个问题,以便我可以调用some_function()实现TOR 的Foo方法Bar?或者我是否只能选择一种实现?

generics traits rust trait-objects

5
推荐指数
1
解决办法
471
查看次数

如何将结构体 Vec 强制转换为特征对象 Vec?

尝试创建一个由HashMap向量​​组成的数据库结构。每个Vec包含Box<dyn Model>.

use std::collections::HashMap;

trait Model {
    fn id(&self) -> i32;
}

struct User;
struct Message;

impl Model for User {
    fn id(&self) -> i32 { 4 }
}

impl Model for Message {
    fn id(&self) -> i32 { 3 }
}

struct DB {
    users: Vec<Box<User>>,
    messages: Vec<Box<Message>>,
    tables: HashMap<String, Vec<Box<dyn Model>>>,
}

impl DB {
    fn new() -> Self {
        let users: Vec<Box<User>> = Vec::new();
        let messages: Vec<Box<Message>> = Vec::new();
        let mut …
Run Code Online (Sandbox Code Playgroud)

traits rust trait-objects

4
推荐指数
1
解决办法
2150
查看次数

是否有无堆的 trait 对象?

有没有办法在堆栈内存中完全实现 trait 对象?

这是我使用的代码,Box因此是堆内存:

extern crate alloc;
use alloc::vec::Vec;
use alloc::boxed::Box;
pub trait ConnectionImp {
    fn send_data(&self);
}

pub struct Collector {
    pub connections: Vec<Box<dyn ConnectionImp>>
}

impl Collector {
    pub fn new() -> Collector {
        Collector {
            connections: Vec::with_capacity(5),
        }
    }
    pub fn add_connection(&mut self,conn: Box<dyn ConnectionImp> ){
        self.connections.push(conn);
    }
}

Run Code Online (Sandbox Code Playgroud)

我尝试使用无堆板条箱,但找不到Box. 以下代码显示了我的努力结果:

use heapless::{Vec,/*pool::Box*/};
extern crate alloc;

use alloc::boxed::Box;

pub trait ConnectionImp {
    fn send_data(&self);
}

pub struct Collector {
    pub connections: …
Run Code Online (Sandbox Code Playgroud)

rust trait-objects

4
推荐指数
1
解决办法
88
查看次数

如何实现 Mul Trait 以使自定义结构类型以两种方式工作

// main.rs
#[derive(Clone, Copy)]
struct A(f64, f64);
impl<T> Mul<T> for A
where
    f64: From<T>,
    T: Copy, // f64: Mul<T>,
{
    type Output = A;
    fn mul(mut self, rhs: T) -> Self::Output {
        self.0 = self.0 * f64::from(rhs);
        self.1 = self.1 * f64::from(rhs);
        self
    }
}

impl Mul<A> for i32 {
    type Output = A;
    fn mul(self, mut rhs: A) -> Self::Output {
        rhs.0 = rhs.0 * f64::from(self);
        rhs.1 = rhs.1 * f64::from(self);
        rhs
    }
}

fn main() {
    let mut …
Run Code Online (Sandbox Code Playgroud)

rust trait-objects

4
推荐指数
1
解决办法
1476
查看次数

如何根据 Rust 中的字符串选择结构体?

问题陈述

\n

我有一组结构 、ABCD,它们都实现了一个 Trait\n Runnable

\n
trait Runnable {\n    fn run(&mut self);\n}\nimpl Runnable for A {...}\nimpl Runnable for B {...}\nimpl Runnable for C {...}\nimpl Runnable for D {...}\n
Run Code Online (Sandbox Code Playgroud)\n

我还有一个结构体,用作构造、\n 、和实例Config的规范。ABCD

\n
struct Config {\n    filename: String,\n    other_stuff: u8,\n}\n\nimpl From<Config> for A {...}\nimpl From<Config> for B {...}\nimpl From<Config> for C {...}\nimpl From<Config> for D {...}\n
Run Code Online (Sandbox Code Playgroud)\n

在我的程序中,我想解析一个Config实例并根据字段的值构造A,\n B, C …

string dynamic-dispatch rust trait-objects

4
推荐指数
1
解决办法
138
查看次数