gpt4 book ai didi

rust - 使用 impl Trait 时如何获得 Deref 强制

转载 作者:行者123 更新时间:2023-11-29 08:18:03 24 4
gpt4 key购买 nike

此函数返回类列表集合的第一个元素。它适用于各种不同的类似列表的类型:

fn first<T: Copy>(x: impl Deref<Target=[T]>) -> T {
x[0]
}

例如,编译并运行:

let data: Vec<usize> = vec![3, 4];
assert_eq!(first(data), 3);

let data: &[usize] = &[3, 4];
assert_eq!(first(data), 3);

let data: Rc<[usize]> = Rc::new([3, 4]);
assert_eq!(first(data), 3);

这也编译并运行:

fn stub(x: &[usize]) -> usize {
first(x)
}

let data: &[usize; 2] = &[3, 4];
assert_eq!(stub(data), 3);

assert_eq!(stub(&[3, 4]), 3);

但是编译失败:

let data: &[usize; 2] = &[3, 4];
assert_eq!(first(data), 3); // Fails.

assert_eq!(first(&[3, 4]), 3); // Fails.

错误信息是:

type mismatch resolving `<&[usize; 2] as std::ops::Deref>::Target == [_]`

我想我明白发生了什么。对于每种类型 T有一个独特的类型 <T as Deref>::Target .当T&[usize; 2]目标是 [usize; 2] , 不是 [usize] .编译器能够强制 &[T; 2]&[T]如果我明确要求它,例如通过使用 letstub() ,但如果我不这样做,那么就无法确定需要强制转换。

但是这很令人沮丧。对于人类来说,失败调用的目的是显而易见的,并且编译器理解 Vec<usize> 需要什么。 , Box<[usize]> , Rc<[usize]> , &[usize]依此类推,因此尝试使其适用于 [usize; 2] 似乎并不合理

问题:有没有方便的写法first()这样最后两个电话也可以吗?如果不是,是否有语法要求编译器强制执行 &[usize; 2]&[usize]内联, 不使用 letstub()

Playground .

最佳答案

您想使用 AsRef , 而不是 Deref:

use std::rc::Rc;

fn first<T: Copy>(x: impl AsRef<[T]>) -> T {
x.as_ref()[0]
}

fn main() {
let data: Vec<usize> = vec![3, 4];
assert_eq!(first(data), 3);

let data: &[usize] = &[3, 4];
assert_eq!(first(data), 3);

let data: Rc<[usize]> = Rc::new([3, 4]);
assert_eq!(first(data), 3);

let data: &[usize; 2] = &[3, 4];
assert_eq!(first(data), 3);
}

关于rust - 使用 impl Trait 时如何获得 Deref 强制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54400803/

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