Rust Generics - 无法推断类型参数“T”的类型
Rust Generics - cannot infer type for type parameter `T`
我有一些 Rust FFI 代码想应用到 i32, i64, f32, f64
等等。所以使用通用类型 T 可以帮助我避免重复大块代码。
在这个例子中,我剪切了 i64
并粘贴在 T
中(并用 <T>
装饰了 fn 名称)。 i64 版本工作正常。
pub struct SeriesC {
se: Series,
}
impl SeriesC {
fn new<T>(name: String, data: Vec::<T>) -> SeriesC {
SeriesC {
se: Series::new(&name, data),
}
}
}
#[no_mangle]
pub extern "C" fn se_new(
string: *const c_char,
data: *const *const i64,
len: size_t,
) -> *mut SeriesC {
let se_name = unsafe {
CStr::from_ptr(string).to_string_lossy().into_owned()
};
let mut se_data: Vec<i64> = Vec::<i64>::new();
unsafe {
assert!(!data.is_null());
for item in slice::from_raw_parts(data, len as usize) {
se_data.push(*item as i64);
};
};
Box::into_raw(Box::new(SeriesC::new(se_name, se_data)))
}
似乎无论我尝试什么都会给我错误。我也考虑过使用 Arrays 而不是 Vecs,但我很确定我想要 Vecs,因为编译时不知道长度。这个尝试说:
error[E0277]: the trait bound `polars::prelude::Series: polars::prelude::NamedFrom<Vec<T>, _>` is not satisfied
--> src/lib.rs:20:17
|
20 | se: Series::new(&name, data),
| ^^^^^^^^^^^ the trait `polars::prelude::NamedFrom<Vec<T>, _>` is not implemented for `polars::prelude::Series`
|
= help: the following implementations were found:
<polars::prelude::Series as polars::prelude::NamedFrom<&polars::prelude::Series, str>>
<polars::prelude::Series as polars::prelude::NamedFrom<T, ListType>>
<polars::prelude::Series as polars::prelude::NamedFrom<T, T>>
<polars::prelude::Series as polars::prelude::NamedFrom<T, [&'a str]>>
and 33 others
非常感谢收到任何建议!
当编译器知道类型是 i64
时,它可以看到 Series
实现了所需的 NamedFrom
转换特征,因为 impl<T> NamedFrom<T, [i64]> for Series where T: AsRef<[i64]>
提供了极地图书馆。当 T
完全不受限制时,NamedFrom
没有实现——有一些类型可以替代 T
,而没有 NamedFrom
的实现。
为了使这项工作通用,您需要添加一个合适的边界,以便编译器知道 Series
上有一个 NamedFrom<Vec<T>, [T]>
实现,这将适当地限制您的 [=21] 的使用=] 类型 T
的函数,例如存在实现。
fn new<T>(name: String, data: Vec::<T>) -> SeriesC
where Series: NamedFrom<Vec<T>, [T]>
{ ... }
我有一些 Rust FFI 代码想应用到 i32, i64, f32, f64
等等。所以使用通用类型 T 可以帮助我避免重复大块代码。
在这个例子中,我剪切了 i64
并粘贴在 T
中(并用 <T>
装饰了 fn 名称)。 i64 版本工作正常。
pub struct SeriesC {
se: Series,
}
impl SeriesC {
fn new<T>(name: String, data: Vec::<T>) -> SeriesC {
SeriesC {
se: Series::new(&name, data),
}
}
}
#[no_mangle]
pub extern "C" fn se_new(
string: *const c_char,
data: *const *const i64,
len: size_t,
) -> *mut SeriesC {
let se_name = unsafe {
CStr::from_ptr(string).to_string_lossy().into_owned()
};
let mut se_data: Vec<i64> = Vec::<i64>::new();
unsafe {
assert!(!data.is_null());
for item in slice::from_raw_parts(data, len as usize) {
se_data.push(*item as i64);
};
};
Box::into_raw(Box::new(SeriesC::new(se_name, se_data)))
}
似乎无论我尝试什么都会给我错误。我也考虑过使用 Arrays 而不是 Vecs,但我很确定我想要 Vecs,因为编译时不知道长度。这个尝试说:
error[E0277]: the trait bound `polars::prelude::Series: polars::prelude::NamedFrom<Vec<T>, _>` is not satisfied
--> src/lib.rs:20:17
|
20 | se: Series::new(&name, data),
| ^^^^^^^^^^^ the trait `polars::prelude::NamedFrom<Vec<T>, _>` is not implemented for `polars::prelude::Series`
|
= help: the following implementations were found:
<polars::prelude::Series as polars::prelude::NamedFrom<&polars::prelude::Series, str>>
<polars::prelude::Series as polars::prelude::NamedFrom<T, ListType>>
<polars::prelude::Series as polars::prelude::NamedFrom<T, T>>
<polars::prelude::Series as polars::prelude::NamedFrom<T, [&'a str]>>
and 33 others
非常感谢收到任何建议!
当编译器知道类型是 i64
时,它可以看到 Series
实现了所需的 NamedFrom
转换特征,因为 impl<T> NamedFrom<T, [i64]> for Series where T: AsRef<[i64]>
提供了极地图书馆。当 T
完全不受限制时,NamedFrom
没有实现——有一些类型可以替代 T
,而没有 NamedFrom
的实现。
为了使这项工作通用,您需要添加一个合适的边界,以便编译器知道 Series
上有一个 NamedFrom<Vec<T>, [T]>
实现,这将适当地限制您的 [=21] 的使用=] 类型 T
的函数,例如存在实现。
fn new<T>(name: String, data: Vec::<T>) -> SeriesC
where Series: NamedFrom<Vec<T>, [T]>
{ ... }