我认为以下代码可以工作:
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);
}
但是我得到了一个编译器错误(见这里):
<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 };
如果您的GradFn
实际上是一个裸函数指针(与闭包相反),您可以保留类型别名,如下所示:
use std::num::Num;
use std::fmt::Show;
// this type has to point to a bare function, not a closure
pub type GradFn<T> = for<'a> fn(&'a [T]) -> (T, Vec<T>);
fn minimize<T>(f : GradFn<T>, x0 : &[T])
where T: Show + Num {
// some no-op to test types
println!("{}",f(x0))
}
fn main() {
// this is now a bare function
fn x_squared(x : &[f64]) -> (f64, Vec<f64>) {
return (x[0] * x[0], vec![2.0 * x[0]]);
}
// and this is a pointer to it, that uses your type alias
let x_sq : GradFn<f64> = x_squared;
let (fx, grad) = x_sq(&[2f64]);
println!("fx: {} - grad: {}", fx, grad);
minimize(x_sq, &[3f64]);; // works with minimize as well
}
fn
不定义闭包类型;它定义了裸函数指针(即指向使用fn
关键字定义的函数的指针)。这就是为什么您不能将闭包分配给GradFn
。相反,您希望使用Fn
、FnMut
或Fnonce
。
我需要再做一些更改才能编译此代码:
这是最终代码:
#![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);
}
闭包从封闭的作用中域捕获变量简单明了。这样会有某些后果吗?当然会。观察一下使用闭包作为函数参量的方式是要求为泛型的,它们定义的方式决定了这是必要的(原文:Observe how using a closure as a function parameter requires generics, which is necessary because of how they are defined):
问题内容: 在Swift中,如果闭包仅包含单个语句,它将自动返回从该单个语句返回的值。 并非在所有情况下都感觉很自然。让我们看一个例子: 如您所见,即使闭包只应调用一个简单函数,它也会尝试自动返回其返回值,该返回值的类型为,与返回类型不匹配。 我可以通过实现闭包主体来避免这种情况: 感觉非常奇怪。 有没有更好的方法可以做到这一点,或者这仅仅是我必须忍受的东西? 问题答案: 发生这种情况的原因是单行
我正在尝试获取部分应用的函数的列表,如下所示: 编译器向我产生一个错误: 错误[E0277]:类型std::vec::Vec的值 随后的尝试也没有成功: 1. 也只有这一次尝试最终成功了! 为什么在动态闭包方面类型推断如此糟糕? 为什么在第一次尝试中不起作用? 有没有更好的方法来利用类型推理来表达这样的想法?
问题内容: 关门了 。这个问题需要更加集中。它当前不接受答案。 想要改善这个问题吗? 更新问题,使其仅通过编辑此帖子来关注一个问题。 5年前关闭。 改善这个问题 所有不同类型的SQL之间有什么区别?我听说过PostgreSQL,SQLite,MySQL,SQL等。它们之间有什么区别? 问题答案: SQL 是结构化查询语言,是一种数据库计算机语言,旨在管理关系数据库管理系统(RDBMS)中的数据。
本节介绍的类型别名,就是通过关键字 type 给类型起个别名,类型别名较多应用于联合类型、交叉类型这种复合类型。 1. 慕课解释 类型别名会给类型起个新名字。类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。 用关键字 type 定义类型别名。 2. 举例说明 类型别名不会新建一个类型,而是创建一个新名字来引用此类型。 先看下面几个例子, 原始类型: typ
为什么可以推断闭包表达式的参数类型和返回类型,而不是rust中的函数?