Перемещение объекта вокруг и последующий вызов метода, который потребляет сам объект, приводит к «не может выйти из заимствованного содержимого» - PullRequest
0 голосов
/ 26 октября 2019

Я знаю, что есть 1000 вопросов по этому поводу, но, похоже, ни один из тех, которые я прочитал, не подходит к этой проблеме.

То, что я делаю, заключается в том, что при определенной функции я создаю RusotoFuture (изящик rusoto_s3):

fn execute(&mut self, s3: &S3Client) -> (i64, RusotoFuture<GetObjectOutput, GetObjectError>) {
   ...
   let dl = s3.get_object(GetObjectRequest{
        ...
        ..Default::default()
    });
   return (sz, dl);

Я возвращаю этот объект и сохраняю его:

fn handle_op(&mut self, input: u64) {
   ...
   let (sz, dl) = op.execute( &self.s3.as_ref().unwrap() );
   self.pending = Some(dl);

Позже я хочу вызвать синхронизацию для этого объекта из функции handle_op, проблема в том, чтоподпись потребляет себя (https://rusoto.github.io/rusoto/rusoto_core/struct.RusotoFuture.html#method.sync):

pub fn sync(self) -> RusotoResult<T, E>

А handle_op занимает &mut self, поэтому у меня нет права собственности на RusotoFuture.

fn execute(&mut self, req: &mut RusotoFuture<GetObjectOutput, GetObjectError>) {
   ...
   let result = req.sync().expect("could not download");

Вызов с:

op.execute(self.pending.as_mut().unwrap() );

И ошибка:

let result = req.sync().expect("could not head");
             ^^^ cannot move out of borrowed content

Как я могу этого добиться? Есть ли в любом случае я могу заставить какой-то небезопасный механизм завладеть им? Я тоже смотрю на Box, но яЯ получаю ту же ошибку. Вероятно, я не правильно ее использую.

1 Ответ

0 голосов
/ 26 октября 2019

Подпись потребляет сама себя, потому что не имеет особого смысла сохранять будущее после того, как оно разрешено. Таким образом, вы не должны вызывать синхронизацию по ссылке. Но из вашего вопроса непонятно, что называется:

let result = req.sync().expect("could not download");
let result = req.sync().expect("could not head");
         ^^^ cannot move out of borrowed content

Это одна и та же строка, и вы изменили строку, или это разные строки и т. Д.?

Но я все еще могупопробуйте ответить.

let dl = s3.get_object(GetObjectRequest{
    ...
    ..Default::default()
});

RusotoFuture, возвращаемое get_object, не является ссылкой, поэтому

fn handle_op(&mut self, input: u64) {
   ...
   let (sz, dl) = op.execute( &self.s3.as_ref().unwrap() );
   self.pending = Some(dl);

имеет расходуемый d1, даже если он принимает &mut self какАргумент. Таким образом, вы должны изменить функцию выполнения с

fn execute(&mut self, req: &mut RusotoFuture<GetObjectOutput, GetObjectError>) {...}

на

fn execute(&mut self, req: RusotoFuture<GetObjectOutput, GetObjectError>) {...}

, а затем вызвать ее как

op.execute( self.pending.take() );

Есть ли какая-либо причина, которая не возможнав вашей настройке?

...