Rust 如何修改构造函数以接受切片或对数组或向量的引用
这是我的代码的一个简化示例:Rust 如何修改构造函数以接受切片或对数组或向量的引用,rust,Rust,这是我的代码的一个简化示例: #[派生(调试、克隆、复制)] 枚举来自的数据{ fn from(v:&'a[i32])->数据来自{ fn来自(v:&'a[f64])->数据{ 姓名:&'a str, 数据:数据变量Self 哪里 T:在DataVar中,我们可以使用trait将引用转换为数组,或将向量转换为切片。AsRef是一个泛型trait,因此我们需要引入第二个类型参数来表示“中间类型”(切片类型).调用作为_ref后,我们得到了一个切片,可以使用转换为数据 impl<'a>
#[派生(调试、克隆、复制)]
枚举来自的数据{
fn from(v:&'a[i32])->数据来自{
fn来自(v:&'a[f64])->数据{
姓名:&'a str,
数据:数据变量Self
哪里
T:在DataVar中,我们可以使用trait将引用转换为数组,或将向量转换为切片。AsRef
是一个泛型trait,因此我们需要引入第二个类型参数来表示“中间类型”(切片类型).调用作为_ref
后,我们得到了一个切片,可以使用转换为数据
impl<'a> DataVar<'a> {
fn new<T, U>(name: &'a str, data: &'a T) -> Self
where
T: AsRef<U> + ?Sized,
U: ?Sized + 'a,
&'a U: Into<Data<'a>>,
{
Self {
name,
data: data.as_ref().into(),
}
}
}
impl{
fn新(名称:&'a str,数据:&'a T)->Self
哪里
T:AsRef+?尺寸,
U:?尺寸+a,
&“a U:Into这实际上是我的案例的最佳解决方案:
impl{
fn新(名称:&'a str,数据:&'a T)->Self
哪里
T:AsRef+?尺寸,
U:a,
&'a[U]:在我看来,AsRef
似乎不是正确的抽象,原因有两个:第一,一个类型可能(如果不太可能)同时实现AsRef
和AsRef
,但不清楚在这种情况下会发生什么;第二,因为已经有一个内置的语言特性()这可能会将Vec
或&[T;n]
转化为&[T]
,而您并没有利用它
我想编写一个新的
函数,基本上如下所示:
fn new<T>(name: &'a str, data: &'a [T]) -> Self
where
// what goes here?
new
上绑定的特征变得微不足道:
impl<'a> DataVar<'a> {
fn new<T>(name: &'a str, data: &'a [T]) -> Self
where
T: Item,
{
Self {
name,
data: T::into_data(data),
}
}
}
@trentcl您的解决方案太棒了!现在我知道如何利用强制
不过,我对它做了如下调整,我最终将使用这段代码,除非您看到其中的任何缺点,谢谢
#[派生(调试、克隆、复制)]
枚举数据:大小{
fn输入数据(&self)->数据输入数据输入数据{
姓名:&'a str,
data:data DataVar事实上,这是IMHO的最佳解决方案……与我最初的代码非常相似,我只需要在新的
构造函数中进行一个小的修复:
#[派生(调试、克隆、复制)]
枚举来自的数据{
fn from(数据:&'a[i32])->数据来自{
fn来源(数据:&'a[f64])->数据{
姓名:&'a str,
数据:data DataVari您需要引用而不是切片是有原因的吗?您可以从数组和向量创建切片。我正在实现一个库,因此这是为了方便用户。哇,这与我试图实现的非常接近,感谢您的明确解释,但不幸的是,以下内容还不起作用:let x=vec![1,2,3];让xvar=DataVar::new(“x”和&x);呃,这是我从一开始就担心的。对数组引用进行推理是有效的,因为AsRef
只在[T;n]
上实现了一个特定的T
,即[T]
。然而,Vec
实现了AsRef
和AsRef
;这会导致编译器放弃,因此您需要通过编写让xvar=DataVar::new::(“x”、&x);
来指定U
。我想这忽略了提供方便的API的意义(因此,如果我理解正确,就没有办法解决这个问题,既不能从
方法编写其他的,也不能使用宏或不安全的代码。如果我使用trait对象而不是enum变量,我想我也会遇到同样的问题,你能确认一下吗?这不会改变任何事情。当你在函数上使用泛型参数时,这完全是错误的。)不幸的是,无法使用隐式强制(例如,将数组强制到切片,如图所示)。
impl<'a> DataVar<'a> {
fn new<T>(name: &'a str, data: &'a [T]) -> Self
where
T: Item,
{
Self {
name,
data: T::into_data(data),
}
}
}
impl<'a, T> From<&'a [T]> for Data<'a>
where
T: Item,
{
fn from(v: &'a [T]) -> Self {
T::into_data(v)
}
}