aco*_*tad 4 match rust xlsxwriter pyo3
我对 Rust 非常非常陌生,并且由于我强大的弱类型编程背景,我一直在努力解决它。
下面的代码应将通过 PYO3 从 Python 接收的数据写入 XLSX 工作表中。我只是不知道如何处理最后一个匹配,因为“value”是 PyAny 类型(也就是说,它的方法 extract 可以输出多种类型,例如 String、f32 等,并且我想要根据提取的特定行为类型)。
也许我可以为每个潜在的提取类型链接匹配(如果第一个输出 Err,请尝试下一个),但我怀疑可能有更好的方法。也许我只是用错误的设计来解决这个问题。任何见解都将受到欢迎。
pub trait WriteValue {
fn write_value(&self, worksheet: &mut Worksheet, row: u32, col: u16, format: Option<&Format>) -> Result<(), XlsxError>;
}
impl WriteValue for String {
fn write_value(&self, worksheet: &mut Worksheet, row: u32, col: u16, format: Option<&Format>) -> Result<(), XlsxError> {
worksheet.write_string(row, col, &self, format)
}
}
impl WriteValue for f32 {
fn write_value(&self, worksheet: &mut Worksheet, row: u32, col: u16, format: Option<&Format>) -> Result<(), XlsxError> {
worksheet.write_number(row, col, f64::from(*self), format)
}
}
fn _write(path: &str, data: HashMap<u32, &PyList>, _highlight: Option<&PyDict>) -> Result<(), XlsxError> {
let workbook = Workbook::new(path);
let mut worksheet = workbook.add_worksheet(None)?;
let format_bold = workbook.add_format().set_bold();
for (row_index, values) in data {
let mut col_idx: u16 = 0;
for value in values {
col_idx += 1;
let row_format= match &row_index {
0 => Some(&format_bold),
_ => None
};
match value.extract::<String>() {
Ok(x) => x.write_value(&mut worksheet, row_index.clone(), &col_idx -1, row_format)?,
Err(_) => { }
}
}
}
workbook.close()
}
Run Code Online (Sandbox Code Playgroud)
这主要是 pyo3 API 问题,我认为 pyo3 没有内置的“multiextract”,尽管我对它不是很熟悉,所以可能是这样。
然而,首先,由于您不关心子句,因此Err您可以通过简单地链接if let语句来简化代码,它们是语法糖,但对于一元或二元布尔条件,它们确实很方便,例如
if let Ok(x) = value.extract::<String>() {
x.write_value(...)
} else if let Ok(x) = value.extract::<f32>() {
// handle this case and possibly add a bunch more
} else {
// handle no case matching (optional if should be ignored)
}
Run Code Online (Sandbox Code Playgroud)
其次,看起来 pyo3 可以让您派生 enums,因为WriteValue显然这是一个内部特征,派生相应的 enum 是有意义的:
#[derive(FromPyObject)]
enum Writables {
#[pyo3(transparent, annotation = "str")]
String(String),
#[pyo3(transparent, annotation = "float")]
Float(f32),
// put the other cases here
}
Run Code Online (Sandbox Code Playgroud)
然后您可以extract立即匹配所有变体(并单独处理“不支持的类型”)。
事实上,此时该特征可能是不必要的,除非它用于其他东西,否则您可以直接将您的write_value方法放在枚举上。
旁注:将 python float (这是一个双精度)提取为 anf32然后立即将其扩大为 anf64以将其写出来似乎......很奇怪。为什么不f64首先提取 an 呢?
| 归档时间: |
|
| 查看次数: |
770 次 |
| 最近记录: |