wye*_*r33 1 methods traits rust
也许我的术语是错误的,但是有没有一种方法可以使用后缀表示法在Rust中调用函数而不定义新特性?基本上,我有一个向量,&str并且我想将它们转换为带符号的字符串myvec.as_string()。目前,我可以使用代码执行此操作
trait Foo {
fn as_string(&self) -> String;
}
impl Foo for Vec<&str> {
fn as_string(&self) -> String {
let mut mystr = self
.iter()
.fold(String::new(),|sum,s| format!("{}{}:", sum, s));
mystr.pop();
mystr
}
}
fn main() {
let my_vec = vec!["bar", "buz", "baz"];
use crate::Foo;
println!("{}", my_vec.as_string());
}
Run Code Online (Sandbox Code Playgroud)
就是说,为了完成这项工作,我需要定义一个Foo我并不真正在意的特性,并且需要use crate::Foo在调用to之前打开该特性as_string。有没有更好的方法可以做到这一点?而且,要明确一点,我想尽可能避免使用该表示法as_string(myvec),因为后缀表示法非常适合将命令链接在一起。
这是常见的模式!
如果要向另一个包装箱中定义的类型添加方法,则官方方法是定义一个特征并为该类型实现。如果类型是来自其他箱子,则这是唯一的方法。
一个普遍的例子是条板箱itertools,它使用特征向每个现有的实现中添加有用的方法std::iter::Iterator。
Itertools就像您描述的那样工作。有一个特征可以声明许多方法:
pub trait Itertools : Iterator {
fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>
where J: IntoIterator<Item = Self::Item>,
Self: Sized
{
interleave(self, other)
}
// etc...
}
Run Code Online (Sandbox Code Playgroud)
它为所有Iterators 定义:
impl<T: ?Sized> Itertools for T where T: Iterator { }
Run Code Online (Sandbox Code Playgroud)
而且,只要您想使用这些额外的方法,就可以导入它:
use itertools::Itertools;
let it = (1..7).interleave(vec![-1, -2]);
itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);
Run Code Online (Sandbox Code Playgroud)