请考虑以下代码:
trait Trait<T> {}
fn foo<'a>(_b: Box<dyn Trait<&'a usize>>) {}
fn bar(_b: Box<dyn for<'a> Trait<&'a usize>>) {}
Run Code Online (Sandbox Code Playgroud)
这两个函数foo和bar似乎接受Box<Trait<&'a usize>>,虽然foo比更简明做它bar.他们之间有什么区别?
另外,在什么情况下我需要for<>像上面那样的语法?我知道Rust标准库在内部使用它(通常与闭包有关),但为什么我的代码需要它呢?
我正在尝试在Rust中实现泛型函数,其中对参数的唯一要求是应该定义乘法运算.我正在尝试实现一个通用的"权力",但将使用更简单的cube功能来说明问题:
use std::ops::Mul;
fn cube<T: Mul>(x: T) -> T {
x * x * x
}
fn main() {
println!("5^3 = {}", cube(5));
}
Run Code Online (Sandbox Code Playgroud)
编译时我收到此错误:
error[E0369]: binary operation `*` cannot be applied to type `<T as std::ops::Mul>::Output`
--> src/main.rs:4:5
|
4 | x * x * x
| ^^^^^^^^^
|
= note: an implementation of `std::ops::Mul` might be missing for `<T as std::ops::Mul>::Output`
Run Code Online (Sandbox Code Playgroud)
这是什么意思?我选择了错误的特质吗?我该如何解决这个问题?
我正在使用在外部包中定义的I2CDevice特征,如下所示:
pub trait I2CDevice {
type Error: Error;
// members
}
Run Code Online (Sandbox Code Playgroud)
它或它的任何成员都不包含任何通用参数.
我正在为任何I2CDevice实现创建一个装饰器,它委托给内部/具体I2CDevice,添加控制台打印以用于诊断目的:
struct debugDeviceDecorator<'a, T: I2CDevice<Error = LinuxI2CError> + Sized + 'a> {
device: &'a mut T,
}
impl I2CDevice__A__ for debugDeviceDecorator__B__ {
type Error = LinuxI2CError;
fn read(&mut self, data: &mut [u8]) -> Result<(), Self::Error> {
println!("read: data: {:?}", data);
self.device.read(data)
}
// etc.
}
Run Code Online (Sandbox Code Playgroud)
我想不出该怎么把到位的__A__和__B__.
当我不使用任何泛型参数时,我得到编译器错误:预期的1个生命周期参数和预期的1个类型参数.
我最好的猜测是__A__留空,因为定义I2CDevice不需要泛型参数,然后镜像用于debugDeviceDecorator结构本身的类型参数代替 …
我想从数组中删除重复的元素:
use itertools::Itertools;
use std::collections::HashSet;
#[derive(Debug)]
struct Person {
name: String,
age: u32,
}
fn main() {
let arr = [
Person { name: "aaa".to_string(), age: 10 },
Person { name: "bbb".to_string(), age: 20 },
Person { name: "bbb".to_string(), age: 20 },
Person { name: "ccc".to_string(), age: 30 },
];
// Way 1:
let arr2 = {
let names: Vec<_> = arr.iter().map(|v| v.name.clone()).unique().collect();
names
.iter()
.map(|name| arr.iter().find(|person| &person.name == name).unwrap())
.collect::<Vec<_>>()
};
dbg!(arr2);
// Way 2:
let arr2 = { …Run Code Online (Sandbox Code Playgroud)