这个解决方案似乎相当不优雅:
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
的两个结果,因此最好将元组直接分配给两个变量first
和last
,而不是看似随心所欲-length Vec
。我似乎无法用元组做到这一点。collect()
有两个实例,我想知道它是否可以减少到一个(甚至为零)。答案 0 :(得分:3)
Result<Vec<u8>, Error>
我建议您返回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
这样的检查对我来说并不重要。
另见: