问题标签 [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 - “借用时临时价值下降”与捕获关闭
请考虑以下示例(游乐场):
这会产生以下编译错误:
这种情况是有道理的,因为我传递给的闭包dog.set_formatter(...)
确实是一个临时的(我猜)当执行继续时被释放dog.bark();
。
我知道在实现中摆脱显式生命周期注释set_formatter
似乎满足编译器(注意'a
之前缺少的dyn
):
但是,我不明白以下内容:
println!("{}", x);
当我在闭包内注释掉时,为什么问题会消失?我仍在传递一个我希望编译器抱怨的临时文件,但事实并非如此。- 当我在最后注释掉时,为什么问题会消失
dog.bark();
?同样,我仍在传递一个已释放的临时闭包,但现在编译器很高兴。为什么?
vector - 为什么 Vec.sort() 似乎需要静态生命周期?
这是我遇到的问题的一个非常简化的示例,但是给定一个trait Thing
which implementsOrd
和一个struct Object
which implements Thing
,我有以下结构:
它本质上需要一个键和一个Object
,并使用给定的键将对象添加到 a HashMap
of Vec
s 中。我知道这不是执行此操作的最佳方法,但我想保持简单以进行说明。
编译器在调用时抱怨things.sort()
以下错误:
如果我在此示例中删除所有'a
生命周期,则代码将编译。但对于我的实际用例,我需要允许非静态生命周期。
有人可以解释这里发生了什么吗?sort()
真的需要Vec
包含具有静态生命周期的项目吗?如果是,为什么?
有没有好的解决方法?
generics - 如何在 Rust 中创建对通用特征对象的引用的 Vec?
我是 Rust 的新手。我的背景是Java。我正在尝试解决以下问题。
- 我有一个
trait Fuel
为struct Diesel
and实现的struct Gas
。 - 我也有一个
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>
,但我想通过动态调度来最小化位置。
types - 在类型别名上调用静态方法
在使用盒装闭包时,我遇到了以下问题:
在第一种情况下,我使用类型别名来引用方法,而在第二种情况下new
我直接使用。Rc
在第一种情况下,编译器抱怨:
但第二种情况效果很好。有人可以解释一下区别吗?有什么方法可以new
通过类型别名引用还是我需要自己包装它?
rust - 在 Rust 中使用泛型、特征别名和构造函数
语境
我有一个DataStore<Key,Value>
特征可以抽象出数据存储。(例如,我可以为包装Vecs
和HashMaps
. (编辑self
:在特征定义中添加了引用,如下。)
我现在想定义一个Thing
包含两个数据存储的结构:一种类型Apple<T>
的存储, 和另一种类型的存储,Banana<T>
。这是我的第一次尝试,
这种方法使用起来很麻烦,因为<K, T, AppleStore, BananaStore> where ...
每当我想传递Thing
给一个函数或实现一个特征时,我必须总是输入,Thing
即使所述函数或特征不关心这两个商店中的任何一个。例如,如果我想实现一个特征,它对Thing
其他类型的属性执行一些不相关的操作,T
我仍然必须告诉它关于K
,AppleStore
和BananaStore
.
我了解了类型别名并尝试了以下方法:
当我尝试BananaStore
在Thing
的构造函数中创建一个新的时,出现了一个新问题。这在尝试 #1 中是允许的,因为特征允许实现 (1) 不&self
作为参数和 (2) 返回类型的函数Self
。但这在尝试 #2 中是不允许的,因为动态特征需要事物是Size
d 并且返回是不允许的Self
。(或者其他的东西?)
问题
我是否需要创建一个BananaStore
外部Thing
并将其作为参数传递,或者有没有办法BananaStore
从外部隐藏构造?ThingBuilder
如果我的目标之一是隐藏不必要的(可选)对象创建,我想类似 a的方法可能是一种有效的方法。但我也不想提供一个默认的实现者:用户应该明确声明使用BananaStore
哪种类型。DataStore
BananaStore
我以这种方式提出问题,因为最终我希望Thing
'在多个实例AppleStore
之间实际共享;Thing
也就是说,多个可以在商店Things
中引用相同的内容。Apple<T>
但每个Thing
人都会有自己的BananaStore
。我知道这需要使用Rc
orArc
或类似的东西,AppleStore
但是当我到达它时我会越过那座桥。
rust - 使用“?”进行自动错误转换 自定义类型的运算符
我正在努力理解?
运营商的细微差别。采取以下代码:
我认为custom()
应该编译。RandomError
是 a StdError
,所以RandomErr
应该可以转换为 ,MyError
因为有一个用于转换 from 的 impl StdError
,不是吗?
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>>
似乎有点矫枉过正......
rust - 断言特征对象的相等性?
通常的assert_eq!
宏要求 PartialEq 跨结构实现 - 我有一个特征对象向量Vec<Box<dyn Element>>
,其中 Element 是需要调试的特征,pub trait Element: std::fmt::Debug
。我不能同样要求PartialEq
,因为它需要 Self 作为类型参数,编译器无法将其制成特征对象。
我见过的解决方案涉及在特征定义中需要一个 eq 关联函数,这对我没有吸引力,因为这只是调试代码,而且我认为包含一个无用的方法是没有好处的并且可能会在cargo test
构建之外对 trait 的 API 进行混淆。
有没有其他(可能不安全的)方法来比较两个特征对象?
rust - 特征对象的 Rust 向量的类型推断不正确
我无法理解以下错误:
编译错误:
错误发生在我尝试创建 C 的那一行。有趣的是,如果我按照以下方式创建 C,那么它可以正常编译。
另一种可行的方法是
我做的另一个实验是将 Cc 的类型更改为 Box 而不是 Vec<Box>,然后无论我如何启动它都会编译。
在我看来,这可能是 Rust 关于特征对象向量的类型推断的一些缺失功能/错误?我对 Rust 还是很陌生,所以对此的任何想法都非常感谢!