gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 07:49:04 25 4
gpt4 key购买 nike

我有一个简单的分类器:

struct Clf {
x: f64,
}

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

我想为这个分类器实现调用运算符。但是,该函数应该能够将 float 或向量作为参数。在向量的情况下,输出是 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,因为 Fn 需要 FnMut,而 FnMut 需要 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,直到我们实现其他特征。

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

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 nightly ,您不能直接调用 c(v) 甚至 c(0.5) (之前有效);我们会得到一个关于函数类型未知的错误。基本上,这些版本的 Rust 不支持函数重载。但是我们仍然可以使用 fully qualified syntax 调用函数,其中 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 通过引用它们:c.classify_slice(&v)

关于operator-overloading - 如何为不同类型的参数实现一个结构的 Fn 特性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38672235/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com