问题标签 [trait-objects]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
168 浏览

generics - Rust:从一个函数返回一个通用结构,其中(仅)是不同的

我正在寻求有关正确语法或 Rust 方法的帮助。我的用例:我有一个通用 struct FileData,它有一个名为provider. 提供者必须实现AsRef<[u8]>,以便数据可以来自静态字节、堆分配内存、内存映射以及可能的其他。我有几种创建方法FileData,它们似乎运行良好。但是有一个

我不明白。该方法总是返回一个 FileData,具体取决于 'mmap' 参数,<T>不同。它可以是<Box<[u8]><Mmap>

我搜索了类似的问题和文章,但可以找到与我的情况相匹配的文章,例如(1)(2)(3)

错误信息是:

0 投票
1 回答
350 浏览

rust - “借用时临时价值下降”与捕获关闭

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

这会产生以下编译错误:

这种情况是有道理的,因为我传递给的闭包dog.set_formatter(...)确实是一个临时的(我猜)当执行继续时被释放dog.bark();

我知道在实现中摆脱显式生命周期注释set_formatter似乎满足编译器(注意'a之前缺少的dyn):

但是,我不明白以下内容:

  1. println!("{}", x);当我在闭包内注释掉时,为什么问题会消失?我仍在传递一个我希望编译器抱怨的临时文件,但事实并非如此。
  2. 当我在最后注释掉时,为什么问题会消失dog.bark();?同样,我仍在传递一个已释放的临时闭包,但现在编译器很高兴。为什么?
0 投票
1 回答
80 浏览

vector - 为什么 Vec.sort() 似乎需要静态生命周期?

这是我遇到的问题的一个非常简化的示例,但是给定一个trait Thingwhich implementsOrd和一个struct Objectwhich implements Thing,我有以下结构:

它本质上需要一个键和一个Object,并使用给定的键将对象添加到 a HashMapof Vecs 中。我知道这不是执行此操作的最佳方法,但我想保持简单以进行说明。

编译器在调用时抱怨things.sort()以下错误:

游乐场链接

如果我在此示例中删除所有'a生命周期,则代码将编译。但对于我的实际用例,我需要允许非静态生命周期。

有人可以解释这里发生了什么吗?sort()真的需要Vec包含具有静态生命周期的项目吗?如果是,为什么?

有没有好的解决方法?

0 投票
2 回答
364 浏览

generics - 如何在 Rust 中创建对通用特征对象的引用的 Vec?

我是 Rust 的新手。我的背景是Java。我正在尝试解决以下问题。

  1. 我有一个trait Fuelstruct Dieseland实现的struct Gas
  2. 我也有一个trait Vehicle泛型Fuel类型参数。Vehicle 用于struct Car<F: Fuel>struct Bus<F: Fuel>

最后,我想将对可能的异构特征对象的引用放在这样的对象中Vec

但我得到这个编译错误:

这个 Vec 中引用的通用类型应该是什么?它猜它应该是类似的东西Vec<&dyn Vehicle>。但是这个变体也不能编译,因为它想提前知道泛型类型参数Vehicle。在 Java 中我只会写List<Vehicle<?>. Rust 中是否有类似的东西?

整个示例可在操场上找到。

PS我显然可以从中删除一个通用参数Vehicle并将其替换为Box<dyn Fuel>,但我想通过动态调度来最小化位置。

0 投票
2 回答
99 浏览

types - 在类型别名上调用静态方法

在使用盒装闭包时,我遇到了以下问题:

在第一种情况下,我使用类型别名来引用方法,而在第二种情况下new我直接使用。Rc

在第一种情况下,编译器抱怨:

但第二种情况效果很好。有人可以解释一下区别吗?有什么方法可以new通过类型别名引用还是我需要自己包装它?

0 投票
1 回答
285 浏览

rust - 在 Rust 中使用泛型、特征别名和构造函数

语境

我有一个DataStore<Key,Value>特征可以抽象出数据存储。(例如,我可以为包装VecsHashMaps. 编辑self:在特征定义中添加了引用,如下。)

我现在想定义一个Thing包含两个数据存储的结构:一种类型Apple<T>的存储, 和另一种类型的存储,Banana<T>。这是我的第一次尝试,

这种方法使用起来很麻烦,因为<K, T, AppleStore, BananaStore> where ...每当我想传递Thing给一个函数或实现一个特征时,我必须总是输入,Thing即使所述函数或特征不关心这两个商店中的任何一个。例如,如果我想实现一个特征,它对Thing其他类型的属性执行一些不相关的操作,T我仍然必须告诉它关于K,AppleStoreBananaStore.

我了解了类型别名并尝试了以下方法:

当我尝试BananaStoreThing的构造函数中创建一个新的时,出现了一个新问题。这在尝试 #1 中是允许的,因为特征允许实现 (1) 不&self作为参数和 (2) 返回类型的函数Self。但这在尝试 #2 中是不允许的,因为动态特征需要事物是Sized 并且返回是不允许的Self。(或者其他的东西?)

问题

我是否需要创建一个BananaStore外部Thing并将其作为参数传递,或者有没有办法BananaStore从外部隐藏构造?ThingBuilder如果我的目标之一是隐藏不必要的(可选)对象创建,我想类似 a的方法可能是一种有效的方法。但我也不想提供一个默认的实现者:用户应该明确声明使用BananaStore哪种类型。DataStoreBananaStore

我以这种方式提出问题,因为最终我希望Thing'在多个实例AppleStore之间实际共享;Thing也就是说,多个可以在商店Things中引用相同的内容。Apple<T>但每个Thing人都会有自己的BananaStore。我知道这需要使用RcorArc或类似的东西,AppleStore但是当我到达它时我会越过那座桥。

0 投票
1 回答
46 浏览

rust - 使用“?”进行自动错误转换 自定义类型的运算符

我正在努力理解?运营商的细微差别。采取以下代码:

链接到游乐场

我认为custom()应该编译。RandomError是 a StdError,所以RandomErr应该可以转换为 ,MyError因为有一个用于转换 from 的 impl StdError,不是吗?

0 投票
1 回答
213 浏览

memory-management - 你如何转换一个盒子到 Rc?

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

使用 a Box<T>of some T: Sized,我们可以做到Rc::new(*my_box),但不幸的是,这不适用于未调整大小的 trait 对象

这是一个过于简化的示例,希望可以澄清问题:

游乐场链接

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

有解决方法吗?

或者,如果这种类型的转换是不可能的,那么推荐的存储特征对象的方法是什么,该对象可以被变异到某个点,然后在该点之后与程序的其余部分不可更改地共享?

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

0 投票
1 回答
188 浏览

rust - 断言特征对象的相等性?

通常的assert_eq!宏要求 PartialEq 跨结构实现 - 我有一个特征对象向量Vec<Box<dyn Element>>,其中 Element 是需要调试的特征,pub trait Element: std::fmt::Debug。我不能同样要求PartialEq,因为它需要 Self 作为类型参数,编译器无法将其制成特征对象。

我见过的解决方案涉及在特征定义中需要一个 eq 关联函数,这对我没有吸引力,因为这只是调试代码,而且我认为包含一个无用的方法是没有好处的并且可能会在cargo test构建之外对 trait 的 API 进行混淆。

有没有其他(可能不安全的)方法来比较两个特征对象?

0 投票
1 回答
165 浏览

rust - 特征对象的 Rust 向量的类型推断不正确

我无法理解以下错误:

编译错误:

错误发生在我尝试创建 C 的那一行。有趣的是,如果我按照以下方式创建 C,那么它可以正常编译。

另一种可行的方法是

我做的另一个实验是将 Cc 的类型更改为 Box 而不是 Vec<Box>,然后无论我如何启动它都会编译。

在我看来,这可能是 Rust 关于特征对象向量的类型推断的一些缺失功能/错误?我对 Rust 还是很陌生,所以对此的任何想法都非常感谢!