2

这是关于这个问题的简短示例。

#[fixed_stack_segment]
fn test(func: extern "C" fn() -> ~str) -> ~str {
    func()
}
extern "C" fn func1() -> ~str {
    ~"hello"
}

fn main() {
    let func2 = || -> ~str { ~"world" };
    println(test(func1));
    println(test(func2));
}

然后,rustc 因错误而停止。

st.rs:13:17: 13:22 error: mismatched types: expected `extern "C" fn() -> ~str` but found `&fn<no-bounds>() -> ~str` (expected extern fn but found fn)
st.rs:13     println(test(func2));

我找不到使 lambda 成为 extern fn 的方法。

我应该怎么办?

4

1 回答 1

3

闭包语法始终是&fnor ~fn,并且要生成extern "ABI" fn(对于 的任何值ABI,包括Rust),需要使用完整的函数声明。

#[fixed_stack_segment]
fn test(func: extern "C" fn() -> ~str) -> ~str {
    func()
}
extern "C" fn func1() -> ~str {
    ~"hello"
}

fn main() {
    extern "C" fn func2() -> ~str { ~"world" } 

    println(test(func1));
    println(test(func2));
}

也有一些关于允许 lambdas 创建非闭包的讨论,ABI 与类型签名中的其他任何东西一样被推断出来,但这还没有实现。


然而,正如 Vladimir Matveev 所说,闭包和普通函数之间存在根本区别,这意味着当作为extern fn. 不同之处在于闭包可以捕获(引用)变量,即

let n = 1;
let f = || { n + 1 }; 

这意味着闭包有效地表示为

struct AndFn { // &fn
    env: &Environment,
    func: extern "Rust" fn()
}

struct TwiddleFn { // ~fn
    env: ~Environment,
    func: extern "Rust" fn()
}

whereEnvironment是一个结构,其中包含该闭包的所有捕获变量(每个都不同&fn,因为每个捕获不同的东西);thefunc是指向闭包代码的函数指针,它是在调用闭包时执行的代码;如果闭包捕获任何变量,func则将要求env存在。extern fn因此,lambda 语法只有在不捕获任何变量时才能创建普通的 s。

于 2013-10-16T11:59:22.397 回答