如何在 Rust 中命名关联函数的类型?
How to name the type of an associated function in Rust?
我正在尝试编写对操作通用的代码,但也有常用函数的便利函数,比如加法,我想为所有类型定义它 T: Add
。
如果我定义独立函数,这很好用,因为我可以在 return 值中使用 impl Trait
来隐藏不透明类型。
但是,如果我想在特征中定义这个函数,我不得不命名 <T as Add>::add
的类型。我该怎么做?
use std::ops::Add;
struct Operation<T, F>
where
F: Fn(T, T) -> T,
{
arg: T,
f: F,
}
fn addition<T>(arg: T) -> Operation<T, impl Fn(T, T) -> T>
where
T: Add<Output = T>,
{
Operation { arg, f: T::add }
}
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, impl Fn(T, T) -> T>;
//fn addition(self) -> Operation<T, ???>;
}
错误:
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> src/main.rs:22:39
|
22 | fn addition(self) -> Operation<T, impl Fn(T, T) -> T>;
| ^^^^^^^^^^^^^^^^^^
特征方法的 return 位置不允许 impl Trait
的原因是因为该方法可以有多个实现,而 impl Trait
仅在有一个时才有效函数或方法的单一实现。
一种选择是使用盒装特征对象闭包:
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, Box<dyn Fn(T, T) -> T>>;
}
但是,由于闭包似乎不太可能需要从其环境中捕获变量,因此您可以改用普通函数指针。这为您节省了不必要的堆分配。这是一个简单的 i32
示例,在特征方法 return 类型中使用普通函数指针:
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, fn(T, T) -> T>;
}
struct SomeType {
arg: i32,
}
impl Addable<i32> for SomeType {
fn addition(self) -> Operation<i32, fn(i32, i32) -> i32> {
Operation {
arg: self.arg,
f: i32::add,
}
}
}
这是一个在特征方法 return 类型中使用普通函数指针的通用示例:
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, fn(T, T) -> T>;
}
struct SomeType<T> {
arg: T,
}
impl<T> Addable<T> for SomeType<T>
where T: Add + Add<Output = T>
{
fn addition(self) -> Operation<T, fn(T, T) -> T> {
Operation {
arg: self.arg,
f: T::add,
}
}
}
我正在尝试编写对操作通用的代码,但也有常用函数的便利函数,比如加法,我想为所有类型定义它 T: Add
。
如果我定义独立函数,这很好用,因为我可以在 return 值中使用 impl Trait
来隐藏不透明类型。
但是,如果我想在特征中定义这个函数,我不得不命名 <T as Add>::add
的类型。我该怎么做?
use std::ops::Add;
struct Operation<T, F>
where
F: Fn(T, T) -> T,
{
arg: T,
f: F,
}
fn addition<T>(arg: T) -> Operation<T, impl Fn(T, T) -> T>
where
T: Add<Output = T>,
{
Operation { arg, f: T::add }
}
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, impl Fn(T, T) -> T>;
//fn addition(self) -> Operation<T, ???>;
}
错误:
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> src/main.rs:22:39
|
22 | fn addition(self) -> Operation<T, impl Fn(T, T) -> T>;
| ^^^^^^^^^^^^^^^^^^
特征方法的 return 位置不允许 impl Trait
的原因是因为该方法可以有多个实现,而 impl Trait
仅在有一个时才有效函数或方法的单一实现。
一种选择是使用盒装特征对象闭包:
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, Box<dyn Fn(T, T) -> T>>;
}
但是,由于闭包似乎不太可能需要从其环境中捕获变量,因此您可以改用普通函数指针。这为您节省了不必要的堆分配。这是一个简单的 i32
示例,在特征方法 return 类型中使用普通函数指针:
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, fn(T, T) -> T>;
}
struct SomeType {
arg: i32,
}
impl Addable<i32> for SomeType {
fn addition(self) -> Operation<i32, fn(i32, i32) -> i32> {
Operation {
arg: self.arg,
f: i32::add,
}
}
}
这是一个在特征方法 return 类型中使用普通函数指针的通用示例:
trait Addable<T>
where
T: Add<Output = T>,
{
fn addition(self) -> Operation<T, fn(T, T) -> T>;
}
struct SomeType<T> {
arg: T,
}
impl<T> Addable<T> for SomeType<T>
where T: Add + Add<Output = T>
{
fn addition(self) -> Operation<T, fn(T, T) -> T> {
Operation {
arg: self.arg,
f: T::add,
}
}
}