如何针对不同类型的参数为一个结构实现Fn特性?

石d

我有一个简单的分类器:

struct Clf {
    x: f64,
}

如果观测值小于x,则分类器返回0;如果大于,则返回1 x

我想为此分类器实现调用运算符。但是,该函数应该能够将float或vector用作参数。对于向量,输出为0或1的向量,其大小与输入向量相同:

let c = Clf { x: 0 };
let v = vec![-1, 0.5, 1];
println!("{}", c(0.5));   // prints 1
println!("{}", c(v));     // prints [0, 1, 1]

Fn在这种情况下,如何编写实现

impl Fn for Clf {
    extern "rust-call" fn call(/*...*/) {
        // ...
    }
}
保尔格

简短的答案是:您不能。至少它不会按照您想要的方式工作。我认为最好的证明方法是逐步了解发生的情况,但总体思路是Rust不支持函数重载。

在此示例中,我们将实现FnOnce,因为FnrequireFnMut需要require FnOnce因此,如果我们要对所有这些进行排序,则可以针对其他功能特性进行处理。

首先,这是不稳定的,因此我们需要一些功能标志

#![feature(unboxed_closures, fn_traits)]

然后,让我们impl进行以下操作f64

impl FnOnce<(f64,)> for Clf {
    type Output = i32;
    extern "rust-call" fn call_once(self, args: (f64,)) -> i32 {
        if args.0 > self.x {
            1
        } else {
            0
        }
    }
}

Fn特质族的参数是通过元组提供的,这就是(f64,)语法。这是一个只有一个元素的元组。

这一切都很好,现在我们可以做c(0.5),尽管c在我们实现其他特征之前它会消耗很多

现在让我们对Vecs做同样的事情

impl FnOnce<(Vec<f64>,)> for Clf {
    type Output = Vec<i32>;
    extern "rust-call" fn call_once(self, args: (Vec<f64>,)) -> Vec<i32> {
        args.0
            .iter()
            .map(|&f| if f > self.x { 1 } else { 0 })
            .collect()
    }
}

每晚Rust 1.33之前,您不能直接打电话c(v),甚至不能打电话c(0.5)(以前没有用过);我们会收到有关未知函数类型的错误信息。基本上,这些版本的Rust不支持函数重载。但是我们仍然可以使用完全限定的语法调用函数,其中c(0.5)变为FnOnce::call_once(c, (0.5,))


不知道您的概况,我想简单地通过提供以下Clf两个函数来解决此问题

impl Clf {
    fn classify(&self, val: f64) -> u32 {
        if val > self.x {
            1
        } else {
            0
        }
    }

    fn classify_vec(&self, vals: Vec<f64>) -> Vec<u32> {
        vals.into_iter().map(|v| self.classify(v)).collect()
    }
}

然后,您的用法示例变为

let c = Clf { x: 0 };
let v = vec![-1, 0.5, 1];
println!("{}", c.classify(0.5));   // prints 1
println!("{}", c.classify_vec(v)); // prints [0, 1, 1]

我实际上想制作第二个函数classify_slice使它&[f64]更通用一些,那么您仍然可以Vec通过引用它们将它与s一起使用c.classify_slice(&v)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何专门针对不同类型参数的特征实现?

在PostgreSQL中,如何声明一个接受不同类型参数的可变参数函数?

我如何实现一个数据结构来支持不同类型的元素,就像C ++中的数组一样?

如何使用Golang从一个函数返回不同类型的结构?

为不同类型的参数实现不同的方法

实现一个接受两个不同类的参数的通用函数?

如何为具有6个不同类型和大小的参数的函数实现多处理

我可以声明一个可以采用不同类型的函数或结构吗?

如何使用Go将具有不同类型的一个元素的数组封送为JSON?

一个工厂的通用实现,用于不同类型的类

如何将一个字段移出实现Drop特性的结构?

如何在Go中为不同类型实现容器?

为不同类型注册同一个类

java中的泛型类型:如何定义一个返回多个不同类型的函数

为不同类型实现相同的功能

如何使用垂直模式定义一个函数,该函数的参数可以是2个或更多不同类型?

将一个结构复制到另一个具有相同成员和不同类型的结构

一个指针,用于不同类型的Fortran

如何建立一个将不同类的向量作为参数的函数族?

如何制作一个显示不同类型值比率的数据框?

如何在一个地方处理不同类型的异常?

如何创建一个包含不同类型列表的列表

如何在不同类型的 Java 中创建一个包含 2 个数组的数组

如何编写一个处理不同类型的单元测试?

如何创建一个包含三种不同类型向量的向量

如何使用一个容器处理不同类型的数据?

如何处理来自同一个异常对象的不同类型的异常?

R如何将不同类型的变量打印到一个txt文件中

如何在React Typescript中处理一个父项下的不同类型