标签: trait-objects

匹配返回迭代器的臂?

我有一些代码尝试运行匹配,其中每个分支都可以返回不同的类型,但所有这些类型都实现了Iterator<Item=usize>.

let found: Iterator<Item = usize> = match requirements {
    Requirements::A => MatchingAs { ainternals: [] },
    Requirements::B => MatchingBs { binternals: [] },
    Requirements::C => MatchingCs { cinternals: [] },
};

return found.any(|m| m == 1)
Run Code Online (Sandbox Code Playgroud)

... 哪里MatchingAsMatchingBs, 以及MatchingCs所有impl std::iter::Iterator<Item = usize>

Iterator因为尺寸不合适而碰壁:

let found: Iterator<Item = usize> = match requirements {
    Requirements::A => MatchingAs { ainternals: [] },
    Requirements::B => MatchingBs { binternals: [] }, …
Run Code Online (Sandbox Code Playgroud)

traits matching rust trait-objects

2
推荐指数
1
解决办法
621
查看次数

不同具体类型泛型的 Vec

我有一个特征 Foo,具体类型 A 和 B 都受特征 Foo 的限制。我想返回 a Vec<Foo>,其中 Foo 可以是具体类型 A 或 B,如下所示:

trait Foo { }

pub struct A {}
pub struct B {}

impl Foo for A {}
impl Foo for B {}


fn test() -> Vec<Foo> {
    let generic_vec: Vec<Foo> = Vec::new();
    generic_vec.push(A {});
    generic_vec.push(B {});
    return generic_vec;
}
Run Code Online (Sandbox Code Playgroud)

目前的编译器抛出错误,即未为 Foo 实现 sized trait。我可以将 Foo 包装在一个 Box 中,但我不想返回 trait 对象的 Vec,因为它们会带来运行时开销。

我想知道是否有一些 Rust 泛型特性可以让我返回泛型类型的 Vec 而不必使用特征对象。

rust trait-objects

2
推荐指数
2
解决办法
2203
查看次数

如何将 Rc&lt;RefCell&lt;dyn T&gt;&gt; 传递给需要 &amp;dyn T 的 fn?

我无法将参数传递给 fn。

trait T {}

struct S {
    others: Vec<Rc<RefCell<dyn T>>>
}

impl S {
    fn bar(&self) {
        for o in self.others {
            foo(&o.borrow());
        }
    }
}

fn foo(t: &dyn T) {}
Run Code Online (Sandbox Code Playgroud)

编译器告诉我:

trait T {}

struct S {
    others: Vec<Rc<RefCell<dyn T>>>
}

impl S {
    fn bar(&self) {
        for o in self.others {
            foo(&o.borrow());
        }
    }
}

fn foo(t: &dyn T) {}
Run Code Online (Sandbox Code Playgroud)

我认为这就像在rust 书中的示例中,其中Rc自动取消引用并从我可以调用的 RefCell 中获取值borrow()

我也尝试过显式取消引用,但似乎没有任何效果。

如何调用foo()中的每个dyn T对象 …

dereference rust trait-objects interior-mutability

2
推荐指数
1
解决办法
290
查看次数

将 Arc&lt;RwLock&lt;T&gt;&gt; 转换为 Arc&lt;RwLock&lt;TraitObject&gt;

我正在编写一个带有边和节点的图实现。该图应同时访问,因此我选择将 Edges 和 Nodes 构建为Arc<Mutex<dyn Edge>>and Arc<RwLock<dyn Node>>

不幸的是,我在连接节点/边时遇到编译错误the parameter type 'T' may not live long enough( Playground )。

pub trait Node {
  fn connect(&mut self, edge: EdgeRef);
}

pub type NodeRef = Arc<RwLock<dyn Node>>;

pub trait Edge {
  fn connect(&mut self, node: NodeRef);
}

pub type EdgeRef = Arc<Mutex<dyn Edge>>;

impl<T> Node for Arc<RwLock<T>>
where
  T: Node,
{
  fn connect(&mut self, edge_ref: EdgeRef) {
    let mut node = self.write().unwrap();
    let mut edge = edge_ref.lock().unwrap(); …
Run Code Online (Sandbox Code Playgroud)

generics clone traits rust trait-objects

2
推荐指数
1
解决办法
422
查看次数

`.map(f)` 和 `.map(|x| f(x))` 之间有什么区别?

在做rustlings 时standard_library_types/iterators2.rs,我开始想知道如何std::iter::Iterator::map调用它的参数闭包/函数。更具体地说,假设我有一个功能

// "hello" -> "Hello"
pub fn capitalize_first(input: &str) -> String {
    let mut c = input.chars();
    match c.next() {
        None => String::new(),
        Some(first) => String::from(first.to_ascii_uppercase()) + c.as_str(),
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想用它

// Apply the `capitalize_first` function to a slice of string slices.
// Return a vector of strings.
// ["hello", "world"] -> ["Hello", "World"]
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
    words.into_iter().map(capitalize_first).collect()
}
Run Code Online (Sandbox Code Playgroud)

哪个不编译

error[E0631]: type mismatch in function arguments
  --> exercises/standard_library_types/iterators2.rs:24:27
   |
11 …
Run Code Online (Sandbox Code Playgroud)

iterator functional-programming dereference rust trait-objects

2
推荐指数
1
解决办法
92
查看次数

特征对象如何将具有泛型方法的特征作为参数?

所以特征对象不能有泛型方法——看起来不错。但在这种语言中,使用抽象机制的唯一方法是通过泛型和特征对象。这意味着对于每个特征,我必须事先决定它是否可以用作对象,并在各处使用 dyn 而不是 impl。并且它内部的所有特征都必须以相同的方式来支持这一点。这种感觉非常难看。你能提出什么建议或者告诉我为什么这样设计吗?

fn main() {}

// some abstracted thing
trait Required {
    fn f(&mut self, simple: i32);
}

// this trait doesn't know that it's going to be used by DynTrait
// it just takes Required as an argument
// nothing special
trait UsedByDyn {
    // this generic method doesn't allow this trait to be dyn itself
    // no dyn here: we don't know about DynTrait in this scope
    fn f(&mut self, another: impl Required);
}

// this …
Run Code Online (Sandbox Code Playgroud)

generics abstraction traits rust trait-objects

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

如何在结构中存储闭包对象?

我不知道如何在结构中存储闭包对象。闭包对象的参数和返回值是已知的。这是我的精简代码:

struct Instr<F>
    where F: Fn([i32;4],[i32;3]) -> [i32;4]
{
    name: String,
    op: F
}

fn main()
{
    // Simple example showing the difficulty:
    let tmp : Instr<Fn([i32;4],[i32;3]) -> [i32;4]> = Instr { name: "asd".to_string(), op: |a,b| a};

    // What I really want is something more like this:
    // let instrs = vec![
    //     Instr { name: "asdf", op: |a,b| a },
    //     Instr { name: "qwer", op: |a,b| a }
    // ];
}
Run Code Online (Sandbox Code Playgroud)

坦率地说,我不明白这些错误是什么意思。在我看来,这很简单。封闭件具有类型和已知尺寸。将它存储在相同类型的类型字段中应该很简单。对?

尝试F: ?Sized按照错误消息的提示进行添加并不能修复“编译时大小未知”错误。

有人可以帮我正确编译吗?

struct …
Run Code Online (Sandbox Code Playgroud)

generics closures traits rust trait-objects

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

“借用期间价值下降”并捕获关闭

请考虑以下示例(游乐场):

struct Animal<'a> {
    format: &'a dyn Fn() -> (),
}

impl <'a>Animal<'a> {
    pub fn set_formatter(&mut self, _fmt: &'a dyn Fn() -> ()) -> () {} // Getting rid of 'a here satisfies the compiler
    pub fn bark(&self) {}
}

fn main() {
    let mut dog: Animal = Animal { format: &|| {()} };
    let x = 0;
    dog.set_formatter(&|| {
        println!("{}", x); // Commenting this out gets rid of the error. Why?
    });
    dog.bark(); // Commenting this …
Run Code Online (Sandbox Code Playgroud)

closures lifetime rust borrow-checker trait-objects

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

如何将 Box&lt;dyn Trait&gt; 转换为 Rc&lt;dyn Trait&gt;?

我有一个接收 a 的函数,Box<dyn Trait>需要将其转换为 anRc<dyn Trait>以在线程内共享只读所有权。

随着Box<T>一些T: Sized,我们可以做的Rc::new(*my_box),但不幸的是不起作用的未分级特征的对象

这是一个过于简化的例子,希望能澄清这个问题:

use std::rc::Rc;

pub trait Trait {}

pub struct Foo {}
impl Trait for Foo {}

fn main() {
    let trait_box: Box<dyn Trait> = Box::new(Foo {});
    let trait_rc: Rc<dyn Trait> = Rc::new(*trait_box); // -> Error
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接

我在这里和那里看到了一些关于暴露内部RcBox以支持在Box和之间移动的事情Rc,但 AFAIK 今天不可用。

有解决方法吗?

或者,如果这种类型的转换是不可能的,那么推荐的存储特征对象的方法是什么?

Rc<RefCell<dyn Trait>>当我知道到目前为止我只有一个所有者时,使用 a似乎有点矫枉过正......

memory-management rust trait-objects

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

在枚举中使用 Copy 的超特征时,类型不会实现 Copy 错误

我对 Rust 特征很陌生,所以这可能是由于对超级特征或dyn其他任何东西的误解。我试图在枚举中使用特征对象来:

  • 对可在枚举的该元素中使用的具体类型进行特征绑定
  • 确保枚举仍然可以派生Copy

最小的示例(无法在Rust 游乐场上编译并出现相关错误)是:

#[derive(Copy)]
enum Foo {
    A,
    B(dyn MyTraitWhichIsCopy),
}

trait MyTraitWhichIsCopy: Copy {}
Run Code Online (Sandbox Code Playgroud)

错误是:

error[E0204]: the trait `Copy` may not be implemented for this type
 --> src/lib.rs:1:10
  |
1 | #[derive(Copy)]
  |          ^^^^
...
4 |     B(dyn MyTraitWhichIsCopy),
  |       ---------------------- this field does not implement `Copy`
  |
  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due …
Run Code Online (Sandbox Code Playgroud)

rust trait-objects

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

为什么 Rust 不支持具有关联常量的特征对象?

我知道这是因为对象安全

对象安全特征可以是特征对象的基本特征。如果特征具有以下品质(在RFC 255中定义),则该特征是对象安全的

  • ...
  • 它不能有任何关联的常量。

但是如果用特定值声明关联常量,为什么 Rust 仍然不支持它呢?这是一个例子:

trait Trait {
    const A: i32 = 64;
}

fn fun(t: Box<dyn Trait>) -> bool {
    return  true;
}
Run Code Online (Sandbox Code Playgroud)

我想用函数返回一个常量值,故意省略&self参数,但还是不行。这是代码:

trait Trait {
    fn getA() -> i32 {
        64
    }
}

fn fun(t: Box<dyn Trait>) -> bool {
    return  true;
}
Run Code Online (Sandbox Code Playgroud)

Rust 不支持它有什么低级原因吗?或者只是因为 RFC 规则?

rust trait-objects associated-const

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

从u8切片创建Read trait对象

我正在尝试Readu8切片创建一个特征对象,以便在murmur3包中使用,就像这样

fn main() {
    let mut arr: [u8; 4] = [1, 2, 3, 4];
    let mut slice: &mut [u8] = &mut arr;
    let mut read: &mut std::io::Read = &mut slice;
}
Run Code Online (Sandbox Code Playgroud)

但我明白了

<anon>:4:42: 4:53 error: the trait `std::io::Read` is not implemented for the type `[u8]` [E0277]
<anon>:4     let mut read : & mut std::io::Read = & mut slice;
                                                  ^~~~~~~~~~~
<anon>:4:42: 4:53 help: see the detailed explanation for E0277
<anon>:4:42: 4:53 help: the following implementations …
Run Code Online (Sandbox Code Playgroud)

slice rust trait-objects

0
推荐指数
1
解决办法
613
查看次数