gpt4 book ai didi

rust - 我如何概括一个接受 `&[T]` 的函数,以便我仍然可以使用字节串文字调用它?

转载 作者:行者123 更新时间:2023-11-29 08:07:55 25 4
gpt4 key购买 nike

我从一个有点像这样的函数开始(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 编译器 ( https://github.com/rust-lang/rust/issues/29504 ) 的限制,您的第二个示例目前无法运行。但是,有几种方法可以解决这个问题。

最简单的方法是实现RandomAccess<T>对于所有 C: AsRef<[T]> .这样,它将与 [T; n] 一起使用, &[T] , Vec<T>等:

trait RandomAccess<T> {
fn get_at(&self, index: usize) -> T;
}

impl<T: Copy, C: AsRef<[T]>> RandomAccess<T> for C {
fn get_at(&self, index: usize) -> T {
self.as_ref()[index]
}
}

fn find<T: Copy, C: RandomAccess<T>>(src: C, index: usize) -> T {
src.get_at(index)
}

很遗憾,您将无法添加任何其他 RandomAccess impls 如果你这样做,那么你不妨改变 find收集一些满意的AsRef<[T]> :

fn find<T: Copy, C: AsRef<[T]>> (src: C, index: usize) -> T {
src.get_at(index)
}

或者,如果您需要能够支持不能作为[T] 借用的集合, 你可以实现 RandomAccess<T>对于 [T; n]对于所有 n在某些范围内使用宏:

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]
}
}

macro_rules! impl_random_access {
($($n:expr,)*) => {
$(
impl <T: Copy> RandomAccess<T> for [T; $n] {
fn get_at(&self, index: usize) -> T {
self[index]
}
}
)*
}
}

impl_random_access! {
01,02,03,04,05,06,07,08,
09,10,11,12,13,14,15,16,
17,18,19,20,21,22,23,24,
25,26,27,28,29,30,31,32,
}



fn find<T: Copy, S: ?Sized + RandomAccess<T>>(src: &S, index: usize) -> T {
src.get_at(index)
}

当我们最终获得类型级常量(目前在愿望 list 上)时,您应该能够实现 RandomAccess<T>对于所有 [T; n] .但现在,您需要使用宏。

关于rust - 我如何概括一个接受 `&[T]` 的函数,以便我仍然可以使用字节串文字调用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39624154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com