在下面的代码中,不可能从对实现相同特征的动态大小类型的引用中获得对特征对象的引用。为什么会这样呢?究竟是什么区别&dyn Trait和&(?Sized + Trait)我是否可以使用这两种调用方法特质?
实现的类型FooTraitContainerTrait可能例如具有type Contained = dyn FooTrait或type 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) 我有以下定义:
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或如何更改类型定义以具有该行为和该类型的转换(到子对象的转换)。
我遇到了具有 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 交换)?
谢谢。
我正在学习 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) 我正在尝试在 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 中,您可以为任何实现其他特征组合的类型自动实现特征。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?或者我是否只能选择一种实现?
尝试创建一个由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) 有没有办法在堆栈内存中完全实现 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) // 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) 我有一组结构 、A、B、C和D,它们都实现了一个 Trait\n Runnable。
trait Runnable {\n fn run(&mut self);\n}\nimpl Runnable for A {...}\nimpl Runnable for B {...}\nimpl Runnable for C {...}\nimpl Runnable for D {...}\nRun Code Online (Sandbox Code Playgroud)\n我还有一个结构体,用作构造、\n 、和实例Config的规范。ABCD
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 {...}\nRun Code Online (Sandbox Code Playgroud)\n在我的程序中,我想解析一个Config实例并根据字段的值构造A,\n B, C …
rust ×10
trait-objects ×10
traits ×4
generics ×2
async-await ×1
oop ×1
polymorphism ×1
string ×1
subtyping ×1