闭包的类型别名

Ari*_*ghi 2 closures rust

我会认为以下代码会起作用:

use std::num::{Num};
use std::fmt::{Show};

pub type GradFn<T : Num> = for<'a> fn(&'a [T]) -> (T, Vec<T>);

fn minimize<T : Show, F>(f : GradFn<T>, x0 : &[T]) {
    // some no-op to test types
    print!("{}",f(x0))
}

fn main() {
    let xSquared : GradFn<f64> = |x : &[f64]| -> (f64, Vec<f64>) {
        return (x[0] * x[0], vec![2.0 * x[0]]);
    };
    let (fx, grad)  = xSquared(vec![2.0f64].as_slice());
    print!("{}", fx);
}
Run Code Online (Sandbox Code Playgroud)

但我收到编译器错误(请参阅此处):

<anon>:12:32: 14:4 error: mismatched types: expected `fn(&'a [f64]) -> (f64, collections::vec::Vec<f64>)`, found `|&[f64]| -> (f64, collections::vec::Vec<f64>)` (expected extern fn, found fn)
<anon>:12   let xSquared : GradFn<f64> = |x : &[f64]| -> (f64, Vec<f64>) {
<anon>:13     return (x[0] * x[0], vec![2.0 * x[0]]);
<anon>:14   };
Run Code Online (Sandbox Code Playgroud)

Fra*_*gné 5

fn没有定义闭包类型;它定义了裸函数指针(即指向用fn关键字定义的函数的指针)。这就是为什么您不能将闭包分配给GradFn. 相反,您想使用Fn,FnMutFnOnce

我还需要做一些更改才能编译此代码:

  • On minimizef您编写的参数按值接收未调整大小的类型,这是被禁止的。您还放置了一个F您不使用的类型参数。您可能打算限制FF用作f.
  • 编译器不会让我们在类型参数约束中使用类型别名;我们需要完整地阐明特征。这意味着类型别名基本上没有用。
  • 我删除了 上的类型注释xSquared,这是不必要的。这让我可以完全删除类型别名。

这是最终的代码:

#![feature(unboxed_closures)]

use std::num::{Num};
use std::fmt::{Show};

fn minimize<T: Show, F: FnMut(&[T]) -> (T, Vec<T>)>(mut f: F, x0: &[T]) {
    // some no-op to test types
    print!("{}", f(x0))
}

fn main() {
    let xSquared = |x: &[f64]| -> (f64, Vec<f64>) {
        return (x[0] * x[0], vec![2.0 * x[0]]);
    };
    let (fx, grad)  = xSquared(vec![2.0f64].as_slice());
    print!("{}", fx);
}
Run Code Online (Sandbox Code Playgroud)