简体   繁体   English

如何命名Rust中关联的function的类型?

[英]How to name the type of an associated function in Rust?

I'm trying to write code which is generic over an operation, but also has convenience functions for commonly used ones, like addition, which I want to define for all types T: Add .我正在尝试编写对操作通用的代码,但也具有常用功能的便利功能,例如加法,我想为所有类型定义T: Add

This works fine if I define standalone functions since I can use impl Trait in the return value to hide the opaque type.如果我定义独立函数,这很好用,因为我可以在返回值中使用impl Trait来隐藏不透明类型。

However, if I want to define this function inside a trait, I am forced to name the type of <T as Add>::add .但是,如果我想在特征中定义这个 function ,我不得不将<T as Add>::add How can I do this?我怎样才能做到这一点?

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:错误:

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>;
   |                                       ^^^^^^^^^^^^^^^^^^

The reason impl Trait isn't allowed in the return position of trait methods is because there can be multiple implementations of the method, whereas impl Trait is only valid if there's a single implementation of the function or method.特征方法的返回值 position 中不允许使用impl Trait的原因是因为该方法可以有多个实现,而impl Trait仅在 function 或方法只有一个实现时才有效。

One option would be to use a boxed trait object closure:一种选择是使用盒装特征 object 闭包:

trait Addable<T>
where
    T: Add<Output = T>,
{
    fn addition(self) -> Operation<T, Box<dyn Fn(T, T) -> T>>;
}

However, since it seems unlikely that the closure would ever need to capture variables from its environment you can use a plain function pointer instead.但是,由于闭包似乎不太可能需要从其环境中捕获变量,因此您可以改用普通的 function 指针。 This saves you an unnecessary heap allocation.这为您节省了不必要的堆分配。 Here's a simple i32 example using a plain function pointer in the trait method return type:这是一个简单的i32示例,在 trait 方法返回类型中使用了一个普通的 function 指针:

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,
        }
    }
}

Here's a generic example using plain function pointer in the trait method return type:这是一个在特征方法返回类型中使用普通指针 function 的通用示例:

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,
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM