Box是否需要从函数返回特征?

时间:2019-08-14 11:34:45

标签: rust iterator traits

我有一个函数可以分析从命令行参数收集的字符串。该函数检查接收到的单个参数是否与Unicode代码点符号匹配(例如U+20AC或非BMP字符U-000020AC的特殊情况),如果匹配,则将其转换为{{1} }。如果自变量看起来不像这种符号,则该自变量中的每个字符都将转换为char

该函数返回一个char,其中包含在输入中找到的所有Unicode字符—不管如何指定它们,例如Iterator<Item = char>U+20ACU-000020AC

该函数可以返回三种迭代器:

  • 有效的Unicode代码点表示法:带有单个项目的迭代器
  • 伪造的Unicode代码点表示法:空迭代器
  • 只是一个字符序列:包含所述字符的迭代器

在Rust中,我似乎无法从同一#![feature(trait_alias)] use std::iter; trait CharIterator = Iterator<Item = char>; fn to_chars(input: &str) -> impl CharIterator { if input.starts_with("U+") || input.starts_with("U-") { // A Unicode codepoint reference. let cp = &input[2..]; let c = u32::from_str_radix(cp, 16) .ok() .and_then(std::char::from_u32); match c { Some(c) => Box::new(iter::once(c)) as Box<dyn CharIterator>, // For now, just ignore erronous input. _ => Box::new(iter::empty::<char>()) as Box<dyn CharIterator>, } } else { // Characters as-is. Box::new(input.chars().collect::<Vec<_>>().into_iter()) as Box<dyn CharIterator> } } #[cfg(test)] mod tests { use super::*; #[test] fn to_chars_test() { assert_eq!(vec!('a'), to_chars("a").collect::<Vec<_>>()); assert_eq!(vec!('a', 'b'), to_chars("ab").collect::<Vec<_>>()); assert_eq!(vec!('a'), to_chars("U+0061").collect::<Vec<_>>()); assert_eq!(vec!('漢', '字'), to_chars("漢字").collect::<Vec<_>>()); assert_eq!(vec!('漢'), to_chars("U+6F22").collect::<Vec<_>>()); assert_eq!(None, to_chars("U+9999999").next()); } } 的{​​{1}}分支中返回不同的Iterator实现。人们建议的解决方案是返回match

上面的代码有效,但这是惯用的吗?

还有更优雅的方式吗?

一些背景:我是Rust的新手,但是有Java编程经验。在Java中,最好的做法是对接口而不是实现进行编码,因此返回接口是很常见的。

我是不是通过自动尝试应用这个概念以错误的方式进入Rust编程?

0 个答案:

没有答案