问题标签 [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.
rust - HashMap<&str, &dyn Fn(&str) -> bool> 的“借用时临时值下降”
我有一个HashMap
函数字符串。据我了解,这&dyn Fn(&str) -> bool
是必要的,因为我想同时使用函数和闭包,但是我收到了这个编译错误:
示例代码:
rust - 如何在 Rust 中按值传递盒装特征对象?
我正在编写一些代码,并且具有一种self
按值取值的方法的特征。我想在Box
'd 特征对象上调用此方法(使用Box
及其值)。这可能吗?如果是这样,怎么做?
就代码而言,一个最小的示例类似于以下(不完整的)代码:
我的问题是如何consume_box
用指定的签名填充函数,以便返回的值是通过调用'd 值获得的任何值consume
。Box
我最初写过
作为函数的主体,虽然我意识到这不是一个正确的想法,因为它没有传达出我想要Box
被消费的事实,不仅仅是它的内容,而是我唯一能想到的东西. 这不编译,给出一个错误:
无法移动 dyn Consumable 类型的值:无法静态确定 dyn Consumable 的大小
这对我来说有点令人惊讶,作为 Rust 的新手,我曾认为也许self
参数传递类似于 C++ 中的右值引用(这确实是我想要的 - 在 C++ 中,我可能会通过带有签名的方法来实现它virtual std::uint64_t consume() &&
,std::unique_ptr
通过虚拟析构函数清理被移动的对象),但我猜 Rust 确实是按值传递,将参数移动到之前的位置 - 所以它拒绝代码是合理的。
麻烦的是,我不确定如何获得我想要的行为,我可以在其中使用Box
'd 特征对象。我尝试使用默认实现向特征添加一个方法,认为这可能会让我在 vtable 中获得一些有用的东西:
但是,这会产生错误
特质
Consumable
不能变成对象
当我提到Box<dyn Consumable>
类型时——这并不奇怪,因为编译器弄清楚如何处理参数类型不同的函数Self
会很神奇。
是否可以使用提供的签名实现该功能consume_box
- 甚至在必要时修改特征?
如果它有用,更具体地说,这是一些数学表达式的一种表示的一部分 - 也许玩具模型将是看起来大致如下的特定实现:
其中,在大多数情况下,事物是普通的旧数据(但可能是由于泛型的原因,它的任意大块),但也使其与传递更多不透明的句柄到这类事物兼容 - 因此希望能够与Box<dyn Consumable>
. 至少在语言级别上,这是一个很好的模型来说明我在做什么——这些对象拥有的唯一资源是内存块(与多线程无关,也没有自我引用的恶作剧)——尽管这模型没有捕捉到我拥有的用例是一个对实现使用对象而不是仅仅读取它很有用的用例,也没有适当地建模我想要“打开”enum
直接代表一棵树) - 因此我问的是按值传递而不是尝试重写它以通过引用传递。
rust - 如何为创建具有特征生命周期边界的对象的生产者找到通用边界
我已将我的实际代码简化为这个最小的示例:
我有一种Producer
创建Something
. 并且可以实现的东西Borrower<'b>
,它引入了生命周期。然后,我想限制一个函数perform
来接收Something
具有 trait 的生产者Borrower<'b>
。但是,由于我无法阻止在perform
函数中引入生命周期,因此我认为所有生成的项目都必须为整个函数执行而存在。实际上,它们只是实现的静态对象Borrower<'b>
。但我很难找到正确的界限。
错误消息反映:
也许你可以帮助我。
generics - 我如何施放 Rc> 到 Rc>?
我正在尝试转换Rc<RefCell<Data>>
为Rc<RefCell<dyn Interface>>
(Data
implements Interface
),但在通用方法中是不可能的:
我对非原始强制转换有一个编译错误:
rust - Rust:无法将 Trait RangeBounds 制成对象
我在尝试 Rust 时偶然发现了一个问题,这可能表明我对它的概念有更大的不理解。
我的目标是编写康威生命游戏的变体。我希望在创建单元格或保持活动状态时的值不是硬编码,而是在结构中。我的第一次尝试是创建一个结构
该对象稍后在迭代所有单元格的算法中使用。它工作正常,直到我还想在创建过程中允许其他类型的范围,例如 RangeTo (2..=3)。
我知道我可以将其重写struct Rules
为通用的。
这反过来又会迫使我使我使用的所有算法也都是通用的。仅仅包括两个简单的范围,这似乎是相当多的开销。
另一方面,我将类型变量RangeBounds
直接包含到我的结构中的尝试都没有成功。我尝试了&dyn RangeBounds<usize>
or Box<&dyn RangeBounds<usize>>
,只是为了始终得到错误 E0038 ,即我无法将此特征转换为对象。
有没有其他方法可以完成这项工作,还是有其他我看不到的可行方法?
提前感谢您的所有提示。
struct - 具有特征字段的结构,但可选
假设我有一个结构,其实现写入某处,即写入实现std::io::Write
特征的东西。但是,我不希望结构拥有它。以下代码有效:
但是,现在这个写作功能应该是可选的。我认为这听起来很容易,但现在以下内容无法编译:
因为:
我不确定如何解释。
我尝试通过将相关行更改为:
但后来我得到
我真的不知道如何解释这些错误消息,令人惊讶的是,在没有真正理解的情况下,仅仅在随机的地方撒上&
s 和s 并没有真正到达任何地方!mut
(顺便说一句,我不确定这是否是解决这个问题的“好”方式?我对解决这个问题的完全不同的方法持开放态度,这基本上是可选地将要写入的内容传递到结构中,但没有拥有它的结构。我读到了Box
可能也相关的类型?)
generics - 如何将闭包对象存储在结构中?
我不知道如何将闭包对象存储在结构中。闭包对象的参数和返回值是已知的。这是我的精简代码:
坦率地说,我不明白这些错误是什么意思。在我看来,这很简单。闭包具有类型和已知尺寸。将其存储在相同类型的类型字段中应该很简单。正确的?
尝试F: ?Sized
按照错误消息提示进行添加并不能修复“编译时大小未知”错误。
有人可以帮我正确编译吗?
rust - 如何为迭代器编写具有生命周期的特征和实现?
我试图了解如何为我自己的类型编写 atrait
和 an来处理一些输入数据。impl
我从一个简单的例子开始,我想1, 2, 3, 4
用trait Processor
. 一个实现将跳过第一个元素并将所有剩余的输入加倍。因此它应该看起来像这样:
所以我的假设是我的特征和相应的实现看起来像这样:
此代码不能按原样工作。我收到以下错误:
如果我的输入数据非常大,我不希望将整个数据集保存在内存中(使用的全部要点Iterator
),所以我假设 usingIterator<T>
应该从原始输入源流式传输数据,直到最终聚合或以其他方式处理。但是,就我需要在这里注释的生命周期而言,我不知道这意味着什么。
最终,我Processor
可能会保存来自输入的一些中间数据(例如,用于运行平均计算),因此我可能必须在我的结构上指定生命周期。
处理一些编译器错误时,我尝试将'a
、'static
和'_
生命周期添加到 my dyn Iterator<...>
,但我不太清楚如何传递输入迭代器并懒惰地修改值。
这甚至是一个合理的方法吗?我可能可以将输入存储Iterator<Item = i32>
在我的 struct andimpl Iterator<Item = u32> for SkipOneTimesTwo
中,但是我大概会失去一些能够传递Processor
特征的抽象。
rust - 如何在 Rust 中定义递归特征绑定?
首先,我知道Box
如果我想定义一个递归结构,我可以使用。例如,
但是如何通过模板或特征对象在这些结构上创建特征?由于 的存在fn append_next(...) -> Self
,我不能像这样直接创建特征对象:
而且我们不能退货Option<Box<impl Linkable>>
或impl Linkable
换货fn get_next(&self)
。
然后我通过通用模板尝试了以下实现,但它不起作用。因为我需要T
在构造一个新的LinkNode
.
我最终以这种方式实现它,通过创建其他特征来提供帮助。而且效果很好。再次......还有其他更好的方法吗?
顺便说一句,在上面的探索过程中我还有一些其他问题:为什么 Rust 禁止impl Linkable
糖,比如Box<impl Linkale>
? 为什么impl Linkable
在一个特征中禁止返回?
在Ibraheem的回答之后更新:
除了来自Ibraheem的关联类型实现之外,像这样工作也很好。核心思想是避免 trait 中的递归类型声明。
error-handling - 如何返回带有一般错误的结果
我想编写一个读取文件内容的函数,如果失败则引发错误。我想从 python 脚本调用这个函数,所以我在下面提到了一些 Python,以防它可能相关。
正如我尝试在评论中展示的那样,可能会发生更多的工作来引发其他类型的错误,所以如果可能的话,如果在 Rust(?) 中可能的话,我想使用一个通用错误。如何返回错误,以便可以处理它并将其包装在 python 错误中,如图所示do_work
?不确定我导致以下错误的方法是否朝着正确的方向发展。
错误: