Синтаксис закрытия всегда либо &fn
или ~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));
}
Существует несколько притчи позволяет лямбде создавать не-закрытия тоже с ABI вывода, как и все остальное в сигнатуре типа, но это еще не реализован.
Однако, как говорит Владимир Матвеев, существует фундаментальное различие между закрытием и нормальными функциями, что означает, что один никогда не будет в состоянии использовать все возможности закрытия при передаче в качестве 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()
}
где Environment
это структура, которая содержит все переменный захват для этого закрытия (он различается для каждого &fn
, так как каждый захватывает разные вещи); func
- это указатель функции на код замыкания, который запускается при вызове замыкания; если замыкание фиксирует любые переменные, func
будет требовать существования env
. Таким образом, синтаксис лямбда будет иметь возможность создавать простые extern fn
с, когда он не фиксирует никаких переменных.
Я не думаю, что вы можете, потому что закрытие подразумевает захваченную среду, а внешние функции не имеют среды. Однако я не уверен, давайте подождем более авторитетный ответ. –