如何在Rust中将泛型Vector拼接为String?
解答
错误原因
你给T绑定ToString trait的思路是合理的,但Vec<T>的join方法并不依赖ToString,它依赖标准库的std::slice::Join trait。当你传入&'static str作为分隔符时,该trait要求元素类型T满足Borrow<str>(即能被借用为str),但你的T仅绑定了ToString和Debug,不满足这个约束,因此编译器报错。
修复方案(原需求:分隔符为&str)
既然已经给T绑定了ToString,可以手动遍历集合,将每个元素转为String后再拼接,无需依赖Join trait:
pub fn myjoin<T>(iter: Vec<T>, s: &str) -> String where T: ToString, { let mut result = String::new(); let mut iter = iter.into_iter(); if let Some(first) = iter.next() { result.push_str(&first.to_string()); for item in iter { result.push_str(s); result.push_str(&item.to_string()); } } result }
如果追求简洁,也可以先将元素转为String集合,再用String的join方法:
pub fn myjoin<T>(iter: Vec<T>, s: &str) -> String where T: ToString, { iter.into_iter() .map(|item| item.to_string()) .collect::<Vec<_>>() .join(s) }
进阶:让分隔符类型与T相同
若要让分隔符和元素类型一致,需给T额外绑定Clone trait(因为要在元素间重复插入分隔符),同时保留ToString:
pub fn myjoin<T>(iter: Vec<T>, sep: T) -> String where T: ToString + Clone, { let mut result = String::new(); let mut iter = iter.into_iter(); if let Some(first) = iter.next() { result.push_str(&first.to_string()); for item in iter { result.push_str(&sep.clone().to_string()); result.push_str(&item.to_string()); } } result }
简洁版实现:
pub fn myjoin<T>(iter: Vec<T>, sep: T) -> String where T: ToString + Clone, { let sep_str = sep.to_string(); iter.into_iter() .map(|item| item.to_string()) .collect::<Vec<_>>() .join(&sep_str) }
内容的提问来源于stack exchange,提问作者Talel BELHAJSALEM
相关产品推荐
相关产品推荐

