[英]Rust Generics - cannot infer type for type parameter `T`
I have some Rust FFI code that I would like to apply to i32, i64, f32, f64
and so on.我有一些 Rust FFI 代码想应用于i32, i64, f32, f64
等。 So using a generic type T would help me to avoid repeating large blocks of code.所以使用泛型类型 T 将帮助我避免重复大块代码。
In this example, I have cut out i64
and pasted in T
(and decorated the fn names with <T>
).在这个例子中,我剪掉了i64
并粘贴到T
中(并用<T>
修饰了 fn 名称)。 The i64 version works fine. i64 版本运行良好。
use libc::c_char;
use libc::size_t;
use std::slice;
use std::ffi::*; //{CStr, CString,}
use std::fs::File;
use std::path::{Path};
use polars::prelude::*;//{CsvReader, DataType, DataFrame, Series};
use polars::prelude::{Result as PolarResult};
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)))
}
It seems that whatever I try gives me errors.似乎无论我尝试什么都会给我错误。 I have also considered Arrays instead of Vecs, but I am pretty sure I want Vecs as the length is not known at compile time.我也考虑过数组而不是 Vecs,但我很确定我想要 Vecs,因为在编译时长度是未知的。 This attempt says:这种尝试说:
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
Any advice gratefully received!任何建议都感激不尽!
When the compiler knows that the type is i64
, it can see that Series
implements the required NamedFrom
conversion trait due to the implementation impl<T> NamedFrom<T, [i64]> for Series where T: AsRef<[i64]>
provided by the polars library.当编译器知道类型是i64
时,它可以看到Series
实现了所需的NamedFrom
转换特征,因为实现impl<T> NamedFrom<T, [i64]> for Series where T: AsRef<[i64]>
由极地图书馆。 There isn't an implementation for NamedFrom
when T
is totally unbounded -- there are types you could substitute for T
for which there would be no implementation of NamedFrom
.当T
完全无界时,没有NamedFrom
的实现——有些类型可以替代T
,但没有NamedFrom
的实现。
To make this work generically, you need to add a suitable bound so that the compiler knows that there is a NamedFrom<Vec<T>, [T]>
implementation on Series
, which will appropriately restrict usage of your SeriesC::new()
function to types T
for which such as implementation exists.为了使这项工作通用,您需要添加一个合适的界限,以便编译器知道Series
上有一个NamedFrom<Vec<T>, [T]>
实现,这将适当地限制您的SeriesC::new()
的使用对类型T
的函数,例如存在的实现。
fn new<T>(name: String, data: Vec::<T>) -> SeriesC
where Series: NamedFrom<Vec<T>, [T]>
{ ... }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.