【发布时间】:2017-01-30 03:39:53
【问题描述】:
我从一个有点像这样 (playground) 的函数开始:
fn find <T: Copy> (src: &[T], index: usize) -> T {
// more complex algorithm, involving src goes here
src[index]
}
pub fn main() {
let x = b"abc";
assert_eq!(b'b', find(x, 1));
}
我想概括它,以便我可以为src 使用任何合适的类型。我想出的最好的就是这个(playground):
trait RandomAccess<T> {
fn get_at(&self, index: usize) -> T;
}
impl <T: Copy> RandomAccess<T> for [T] {
fn get_at(&self, index: usize) -> T {
self[index]
}
}
fn find <T: Copy, S: ?Sized + RandomAccess<T>> (src: &S, index: usize) -> T {
// more complex algorithm, involving src goes here
src.get_at(index)
}
pub fn main() {
let x = b"xyz";
assert_eq!(b'y', find(&x[..], 1));
}
但是,我现在不能只调用find(x, 1),我必须创建一个切片:find(&x[..], 1)。
有没有办法使这个通用化,但仍然能够像原始示例一样调用find?
【问题讨论】:
-
似乎 rust 编译器在第一个示例中在幕后做了一些诡计,并允许将
&[u8; 3]强制转换为&[u8],但在第二个示例中不能这样做,因为它不能确定这是意图。基本上是这个问题吗? -
我尝试对 Index
和其他一些东西进行抽象,但我不相信你需要引入这样的抽象——它们往往会使事情复杂化而没有附加价值。其他 src类型find()可以适用于哪些? -
诡计在于:如果目标类型已知,则强制触发。因为
find使用src的类型参数,所以不是。