我有一个通用函数,打印至少两个项目:
use std::fmt::Display;
fn print_min<T: PartialOrd + Display>(a: &T, b: &T) {
println!("min = {}", if a < b { a } else { b });
}
Run Code Online (Sandbox Code Playgroud)
这适用于实现PartialOrd和Display特征的任何东西:
print_min(&45, &46);
// min = 45
print_min(&"a", &"b");
// min = a
Run Code Online (Sandbox Code Playgroud)
必须放入PartialOrd + Display函数定义是一种丑陋的,特别是如果我想拥有一大堆对此进行操作的函数(例如,实现二进制搜索树),或者我的边界变得更复杂.我的第一个倾向是尝试编写一个类型别名:
type PartialDisplay = PartialOrd + Display;
Run Code Online (Sandbox Code Playgroud)
但这给了我一些相当奇怪的编译器错误:
error[E0393]: the type parameter `Rhs` must be explicitly specified
--> src/main.rs:7:23
|
7 | type PartialDisplay = PartialOrd + Display;
| ^^^^^^^^^^ missing reference …Run Code Online (Sandbox Code Playgroud) 我正在实现一个Bit Vector类作为练习,但是只知道Rust不到一周,我遇到了以下代码的问题:
use std::cmp::Eq;
use std::ops::BitAnd;
use std::ops::Index;
use std::ops::Not;
struct BitVector<S = usize>
where S: Sized + BitAnd<usize> + Not + Eq {
data: Vec<S>,
capacity: usize
}
impl<S> BitVector<S>
where S: Sized + BitAnd<usize> + Not + Eq {
fn with_capacity(capacity: usize) -> BitVector {
let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1;
BitVector { data: vec![0; len], capacity: capacity }
}
}
impl<S> Index<usize> for BitVector<S>
where S: Sized + BitAnd<usize> + Not + Eq …Run Code Online (Sandbox Code Playgroud) 根据这个问题和这个回答的问题,不可能简单地定义一个特征别名,如:
trait Alias = Foo + Bar;
Run Code Online (Sandbox Code Playgroud)
解决方法有点难看:
trait Alias : Foo + Bar {}
impl<T: Foo + Bar> Alias for T {}
Run Code Online (Sandbox Code Playgroud)
因此,我想为此定义一个宏.我试过了
macro_rules! trait_alias {
( $name : ident, $base : expr ) => {
trait $name : $base {}
impl<T: $base> $name for T {}
};
}
trait Foo {}
trait Bar {}
trait_alias!(Alias, Foo + Bar);
Run Code Online (Sandbox Code Playgroud)
但它失败了,错误:
src\main.rs:5:17: 5:22 error: expected one of `?`, `where`, or `{`, found `Foo + Bar`
src\main.rs:5 …Run Code Online (Sandbox Code Playgroud) 由于此错误的两个实例,以下代码将无法编译:
错误[E0277]:
Self: std::marker::Sized不满足特征限制
我不明白为什么Sized在这个实例中需要&self和&Any作为指针并且操作不需要知道实现特征的结构的大小,它只需要知道指针本身及其转换的类型和它将具有,因为&self在特征内部实现时是通用的.
我认为这可能是编译器强制执行不必要的约束的一个实例,我考虑过使用生锈的GitHub仓库提出问题,但我想我应该看看,在我提出问题之前,有人在这里知道我不知道的事情.
use std::any::Any;
trait Component: Any {
fn as_any(&self) -> &Any {
self
}
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
Run Code Online (Sandbox Code Playgroud)
替代方法是为实现此特征的结构创建as_any()和as_any_mut()需要函数,但对于那些结构,实现将始终完全按照此处显示到每个单独的字符,从而生成相同样板代码的多个实例.