有没有办法在不定义新特征的情况下使用后缀表示法在 Rust 中调用函数?
Is there a way to use postfix notation to call a function in Rust without defining a new trait?
也许我的术语是错误的,但是有没有办法在不定义新特征的情况下使用后缀表示法调用 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());
}
就是说,为了完成这项工作,我需要定义一个我并不真正关心的名为 Foo
的特征,并且需要先用 use crate::Foo
打开该特征对 as_string
的调用。有没有更好的方法来完成这个?而且,需要明确的是,我想尽可能避免使用符号 as_string(myvec)
,因为后缀符号非常适合将命令链接在一起。
这是一个常见的模式!
如果你想将方法添加到另一个 crate 中定义的类型,官方方法是定义一个特征并为该类型实现它。如果类型来自另一个板条箱,那么这是唯一的方法。
一个无处不在的例子是 crate itertools
,它使用 trait 为 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...
}
它是为所有 Iterator
定义的:
impl<T: ?Sized> Itertools for T where T: Iterator { }
而且,只要你想使用这些额外的方法,你就可以导入它:
use itertools::Itertools;
let it = (1..7).interleave(vec![-1, -2]);
itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);
也许我的术语是错误的,但是有没有办法在不定义新特征的情况下使用后缀表示法调用 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());
}
就是说,为了完成这项工作,我需要定义一个我并不真正关心的名为 Foo
的特征,并且需要先用 use crate::Foo
打开该特征对 as_string
的调用。有没有更好的方法来完成这个?而且,需要明确的是,我想尽可能避免使用符号 as_string(myvec)
,因为后缀符号非常适合将命令链接在一起。
这是一个常见的模式!
如果你想将方法添加到另一个 crate 中定义的类型,官方方法是定义一个特征并为该类型实现它。如果类型来自另一个板条箱,那么这是唯一的方法。
一个无处不在的例子是 crate itertools
,它使用 trait 为 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...
}
它是为所有 Iterator
定义的:
impl<T: ?Sized> Itertools for T where T: Iterator { }
而且,只要你想使用这些额外的方法,你就可以导入它:
use itertools::Itertools;
let it = (1..7).interleave(vec![-1, -2]);
itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);