我发现了this discussion关于元组字符集的问题,但它是从2014年开始的。
给出的例子是:
fn sum(x: i32, y: i32) -> i32 {
x + y
}
fn prepare_args () -> (i32, i32) {
(1, 2)
}
fn main() {
sum(prepare_args()); // Doesn't work
}
建议的解决方案是推出自己的apply
函数:
fn apply<A,B,C>(f: |A,B|->C, t: (A,B)) -> C {
let (a,b) = t;
f(a,b)
}
fn main() {
apply(sum, prepare_args());
}
这是目前最好的方式吗?如果是这样,这里的语法是什么?我使用上述内容包括expected type, found
| at line 1 col 20
,但我收到了一些错误。
是否仍然没有元组splat运算符?
答案 0 :(得分:6)
我认为没有splat运营商。
您从2014年发现的代码来自Rust 1.0之前,因此它已过时。要使apply
函数在1.0之后的Rust中运行,请将其更改为以下内容:
fn sum(x: i32, y: i32) -> i32 {
x + y
}
fn prepare_args() -> (i32, i32) {
(1, 2)
}
fn apply<A, B, C, F>(f: F, t: (A, B)) -> C
where F : Fn(A, B) -> C
{
let (a, b) = t;
f(a, b)
}
fn main() {
let x = apply(sum, prepare_args());
println!("{}", x);
}
此代码在the Rust playground上正确编译并运行。
您也可以使用f(t.0, t.1)
作为apply
的正文,或者在参数列表(Playground)中进行解构:
fn apply<A, B, C, F>(f: F, (a, b): (A, B)) -> C
where F : Fn(A, B) -> C
{
f(a, b)
}
答案 1 :(得分:5)
证明否定总是很难......
据我所知,确实没有元组splat运算符。但是,Fn*
特征族(Fn)只需要一个参数作为元组。
在夜间编译器上,激活一些不稳定的功能,您可以使用:
#![feature(fn_traits)]
#![feature(unboxed_closures)]
fn sum(x: i32, y: i32) -> i32 {
x + y
}
fn prepare_args () -> (i32, i32) {
(1, 2)
}
fn main() {
let func: &Fn(i32, i32) -> i32 = ∑
let result = func.call(prepare_args());
println!("{:?}", result);
}
不太理想,但是在没有对变量的支持的情况下,你总是需要知道元组元素的数量,所以值很低。
答案 2 :(得分:3)
以下版本apply
适用于尺寸从1到6(可以增加)的元组(Playground):
fn main() {
let add1 = |x| x + 1;
let sum2 = ::std::ops::Add::add;
let sum3 = |a, b, c| a + b + c;
assert_eq!(apply(add1, (1,)), 2);
assert_eq!(apply(sum2, (1, 2)), 3);
assert_eq!(apply(sum3, (1, 2, 3)), 6);
}
#[inline(always)]
pub fn apply<Fun, In, Out>(fun: Fun, params: In) -> Out
where ApplyImpl: Apply<Fun, In, Out>
{
ApplyImpl::apply(fun, params)
}
pub trait Apply<Fun, In, Out> {
fn apply(fun: Fun, params: In) -> Out;
}
pub struct ApplyImpl;
macro_rules! impl_apply {
() => ();
($A:ident, $($B:ident,)*) => (
impl_apply!{$($B,)*}
impl<$A, $($B,)* Fun, Out> Apply<Fun, ($A, $($B),*), Out> for ApplyImpl
where Fun: Fn($A, $($B),*) -> Out
{
#[allow(non_snake_case)]
#[inline(always)]
fn apply(fun: Fun, params: ($A, $($B),*)) -> Out {
// use type parameters as var names...
let ($A, $($B),*) = params;
fun($A, $($B),*)
}
}
)
}
impl_apply!{A, B, C, D, E, F,}
我正在考虑为它创造一个箱子。如果我这样做,我会把链接放在这里。