如何在Rust中拼接两个Option<Vec<String>>类型的值
实现方案
你可以通过以下两种通用方式实现需求,两种实现均完全匹配你给出的所有规则:
1. 高可读性match实现
这种写法逻辑清晰,便于后续扩展自定义规则:
/// 拼接两个Option<Vec<T>>,符合你要求的所有规则 fn concat_option_vec<T>(a: Option<Vec<T>>, b: Option<Vec<T>>) -> Option<Vec<T>> { match (a, b) { // 两个都为None时返回None (None, None) => None, // 仅一个为Some时直接返回该Some值 (Some(v), None) => Some(v), (None, Some(v)) => Some(v), // 两个都为Some时拼接Vec (Some(mut v1), Some(v2)) => { v1.extend(v2); Some(v1) } } }
2. 简洁链式调用实现
利用Rust标准库Option的内置方法实现,代码更短:
fn concat_option_vec<T>(a: Option<Vec<T>>, b: Option<Vec<T>>) -> Option<Vec<T>> { // 两个都为Some时执行拼接,否则优先取存在的Some值,都不存在则返回None a.zip(b).map(|(mut v1, v2)| { v1.extend(v2); v1 }).or(a).or(b) }
测试验证示例
你可以用以下代码验证所有场景的正确性:
fn main() { // 场景1:仅第二个为Some let v1 = None; let v2 = Some(vec!["a".to_string(), "b".to_string()]); assert_eq!(concat_option_vec(v1, v2), Some(vec!["a".into(), "b".into()])); // 场景2:仅第一个为Some let v1 = Some(vec!["c".to_string(), "d".to_string()]); let v2 = None; assert_eq!(concat_option_vec(v1, v2), Some(vec!["c".into(), "d".into()])); // 场景3:两个都为Some let v1 = Some(vec!["1".to_string(), "2".to_string()]); let v2 = Some(vec!["3".to_string(), "4".to_string()]); assert_eq!(concat_option_vec(v1, v2), Some(vec!["1".into(), "2".into(), "3".into(), "4".into()])); // 场景4:两个都为None let v1: Option<Vec<String>> = None; let v2: Option<Vec<String>> = None; assert_eq!(concat_option_vec(v1, v2), None); }
说明
两种实现都使用了extend方法拼接Vec,会直接复用第一个Vec的堆空间,消耗第二个Vec的元素,没有额外的不必要内存分配,性能最优。如果不需要复用输入的两个Option
内容的提问来源于stack exchange,提问作者initprism
相关产品推荐
相关产品推荐

