gpt4 book ai didi

generics - 创建由通用NewType索引的通用结构

转载 作者:行者123 更新时间:2023-12-03 11:36:39 25 4
gpt4 key购买 nike

我想创建一个使用通用newtype进行索引的通用结构。理想情况下,它看起来像这样:

use std::marker::PhantomData;

struct Foo<I, T> {
bar: Vec<T>,
_marker: PhantomData<I>,
}

impl <I, T> Foo<I, T> {
fn new(v: Vec<T>) -> Foo<I, T> {
Foo {
bar: v,
_marker: PhantomData,
}
}
fn get(&self, index: &I) -> &T {
// let index: usize = index.0; // I want to use this line.
let index = 0; // This line is incorrect, but compiles.
&self.bar[index]
}
}
通用newtype保证为 usize,如下所示:
pub struct Baz(pub usize);
pub struct Qux(pub usize);
这样可以编译并正确执行类型检查。
fn main() {
let index_b = Baz(1);
let index_q = Qux(1);
let data: Foo<Baz, i32> = Foo::new(vec![1,2,3]);
assert_eq!(*data.get(&index_b), 2);

// Type Checking Violation - Does not compile.
// assert_eq!(*data.get(&index_q), 2);
}
但是请注意 get()函数不正确。您如何告诉编译器 I是一个usize,因此 get()函数将是正确的?

最佳答案

您需要使用某种特征。没有现有的约束来验证I实际上是SomeType(T)才能知道index.0是有效的。
我立即想到的是在新类型上实现Into:

#[derive(Copy, Clone)]
pub struct Baz(pub usize);

impl Into<usize> for Baz {
fn into(self) -> usize {
self.0
}
}
然后您将按值将 index传递给 get:
fn get(&self, index: I) -> &T
where
I: Into<usize>
{
&self.bar[index.into()]
}
其他选项可能是 DerefAsRef,或者使自己的 FooIndex特性变得有意义。

对于 AsRef:
fn get(&self, index: &I) -> &T
where
I: AsRef<usize>
{
&self.bar[*index.as_ref()]
}
Deref:
fn get(&self, index: &I) -> &T
where
I: Deref<Target=usize>
{
&self.bar[**index]
}

关于generics - 创建由通用NewType索引的通用结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64938057/

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