我有一些代码尝试运行匹配,其中每个分支都可以返回不同的类型,但所有这些类型都实现了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)
... 哪里MatchingAs,MatchingBs, 以及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) 我有一个特征 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 而不必使用特征对象。
我无法将参数传递给 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对象 …
我正在编写一个带有边和节点的图实现。该图应同时访问,因此我选择将 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) 在做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
所以特征对象不能有泛型方法——看起来不错。但在这种语言中,使用抽象机制的唯一方法是通过泛型和特征对象。这意味着对于每个特征,我必须事先决定它是否可以用作对象,并在各处使用 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) 我不知道如何在结构中存储闭包对象。闭包对象的参数和返回值是已知的。这是我的精简代码:
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) 请考虑以下示例(游乐场):
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) 我有一个接收 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似乎有点矫枉过正......
我对 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) 我知道这是因为对象安全:
对象安全特征可以是特征对象的基本特征。如果特征具有以下品质(在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 规则?
我正在尝试Read从u8切片创建一个特征对象,以便在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) rust ×12
trait-objects ×12
traits ×4
generics ×3
closures ×2
dereference ×2
abstraction ×1
clone ×1
iterator ×1
lifetime ×1
matching ×1
slice ×1