如何将“x-y”翻译为vec![x,x + 1,... y-1,y]?

时间:2018-03-08 02:35:25

标签: rust readability

这个解决方案似乎相当不优雅:

fn parse_range(&self, string_value: &str) -> Vec<u8> {
    let values: Vec<u8> = string_value
        .splitn(2, "-")
        .map(|part| part.parse().ok().unwrap())
        .collect();

    { values[0]..(values[1] + 1) }.collect()
}
  • 由于splitn(2, "-")只返回任意有效string_value的两个结果,因此最好将元组直接分配给两个变量firstlast,而不是看似随心所欲-length Vec。我似乎无法用元组做到这一点。
  • collect()有两个实例,我想知道它是否可以减少到一个(甚至为零)。

2 个答案:

答案 0 :(得分:3)

琐碎的实施

Result<Vec<u8>, Error>

Playground

我建议您返回expect/unwrap而不是恐慌#![feature(conservative_impl_trait, inclusive_range_syntax)] fn parse_range(string_value: &str) -> impl Iterator<Item = u8> { let pos = string_value.find(|c| c == '-').expect("No valid string"); let (first, second) = string_value.split_at(pos); let first: u8 = first.parse().expect("Not a number"); let second: u8 = second[1..].parse().expect("Not a number"); first..=second } fn main() { println!("{:?}", parse_range("3-7").collect::<Vec<u8>>()); }

每夜实施

我的下一个想法是关于第二次收集。这是一个使用夜间代码的代码示例,但您根本不需要任何收集。

html/text

答案 1 :(得分:3)

不是第一次调用public class Tab4 extends Fragment { private Button btnCertAdd, btnCertDel; private ArrayList CertNames = new ArrayList(), CertNumbers= new ArrayList(), CertIssueDates= new ArrayList(), CertExpireDates= new ArrayList(); private ListViewAdapter listViewAdapter; private FrameLayout frameLayout; private ListView lv; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { frameLayout = new FrameLayout(getActivity()); View view = inflater.inflate(R.layout.dataload_tab4, null); InitView(view); frameLayout.addView(view); return frameLayout; } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); frameLayout. removeAllViews(); LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.dataload_tab4, null); listViewAdapter = new ListViewAdapter(this, CertNames, CertNumbers, CertIssueDates, CertExpireDates); lv = view.findViewById(R.id.listview); lv.setAdapter(listViewAdapter); // null - изначально нихуя нет frameLayout.addView(view); } private void InitView(View view) { btnCertAdd = view.findViewById(R.id.btnaddcert); btnCertDel = view.findViewById(R.id.btndelcert); listViewAdapter = new ListViewAdapter(this, CertNames, CertNumbers, CertIssueDates, CertExpireDates); lv = view.findViewById(R.id.listview); lv.setAdapter(listViewAdapter); // null - изначально нихуя нет } public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); } } ,而是先推进迭代器:

collect

请勿致电let mut values = string_value .splitn(2, "-") .map(|part| part.parse().unwrap()); let start = values.next().unwrap(); let end = values.next().unwrap(); - 将有效错误信息的.ok().unwrap()转换为没有任何信息的Result。只需直接在Option上致电unwrap

如前所述,如果您想要返回Result,则需要致电Vec来创建它。如果你想要return an iterator,你可以。即使在稳定的Rust中也不错:

collect

可悲的是,inclusive ranges are not yet stable,因此您需要继续使用fn parse_range(string_value: &str) -> std::ops::Range<u8> { let mut values = string_value .splitn(2, "-") .map(|part| part.parse().unwrap()); let start = values.next().unwrap(); let end = values.next().unwrap(); start..end + 1 } fn main() { assert!(parse_range("1-5").eq(1..6)); } 或转换为每晚。

  

由于+1只返回任何有效splitn(2, "-")的两个结果,因此最好将元组直接分配给两个变量,而不是看似任意长度的string_value。我似乎无法用元组做到这一点。

Rust的类型系统无法做到这一点。您要求dependent types,这是运行时值与类型系统交互的一种方式。您希望Vec为值splitn和((&str, &str)2&str)返回&str&str。当参数是变量时,这变得更加复杂,特别是当它在运行时设置时。

最接近的解决方法是让运行时检查没有更多值:

3

这样的检查对我来说并不重要。

另见: