Как сохранить значения в Ve c изнутри обратного вызова, который не принимает ve c в качестве аргумента? - PullRequest
2 голосов
/ 28 мая 2020

Я работаю с ящиком, в котором есть механизм обратного вызова. Обратный вызов определяется пользователем, но имеет специальную подпись c, которая не позволяет передавать другие значения. Например:

fn callback(id: u32, value: u32) -> u32;

// and would be used as such
library_function(callback);

Так что это было бы хорошо, если бы мне нужно было только сохранить в файл или, например, распечатать, однако мне нужно сохранить значения в векторе. Я бы сделал, например, Python, используя лямбду с «предопределенными» аргументами:

def mycallback(predefined, id, value)

# and calling it as such
predefined = []
library_function(lambda *args: mycallback(predifined, *args)

Решение может включать другие уловки Rust, однако его нельзя записать в файл каждый раз, поскольку это кажется слишком большой проблемой для производительности.

1 Ответ

6 голосов
/ 28 мая 2020

Просто используйте закрытие:

let mut vec = Vec::new();
library_function(|id, value| {
    vec.push(value);
    id
});

Эквивалент вашего Python кода будет:

fn callback(vec: &mut Vec<u32>, id: u32, value: u32) -> u32 {
    vec.push(value);
    id
}

fn main(){
    let mut predefined = Vec::new();
    library_function(|id, value| callback(&mut predefined, id, value));
}

Причина, по которой мы их называем закрытие - это потому, что они «закрывают» свое окружение. Это позволяет нам использовать (и в данном случае изменять) переменные, которые находятся в области видимости, в которой определено замыкание.

См. Может запечатлеть окружающую среду в Книгу ржавчины .

...