Признак ржавчины, который принимает (необязательно) ссылочный параметр fn

#rust

Вопрос:

По причинам, которые не особенно важны в данном контексте, я хочу иметь возможность сделать что-то очень похожее на

 pub trait MapValue<Out> {
    fn map_value<C>(amp;self, map_func: fn(C, Out), context: C);
}

impl MapValue<i32> for i32 {
    fn map_value<C>(amp;self, map_func: fn(C, i32), context: C) {
        map_func(context, *self)
    }
}

impl MapValue<amp;i32> for i32 {
    fn map_value<C>(amp;self, map_func: fn(C, amp;i32), context: C) {
        map_func(context, self)
    }
}
 

https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=12afa185d3bf8518320f0fd7862aeb79

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

    = note: expected fn pointer `fn(amp;i32, fn(_, amp;i32), _)`
              found fn pointer `fn(amp;i32, for<'r> fn(_, amp;'r i32), _)`
 

Если я попытаюсь сделать время жизни i32 явным, как в

 impl<'a> MapValue<amp;'a i32> for i32 {
    fn map_value<C>(amp;'a self, map_func: fn(C, amp;'a i32), context: C) {
        map_func(context, self)
    }
}
 

https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=f17b29450683c11093315eb17199504d

затем он терпит неудачу с

 note: the anonymous lifetime #1 defined on the method body at 12:5...
  --> src/main.rs:12:5
   |
12 |     fn map_value<C>(amp;'a self, map_func: fn(C, amp;'a i32), context: C) {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 11:6
 

Очевидно, я, должно быть, неправильно делаю аннотации своей жизни, так как вызов map_func возвращается раньше map_value , поэтому должно быть невозможно, чтобы self он не жил достаточно долго, чтобы его можно было передать map_func . Есть какие-нибудь идеи?

Редактировать:

Я могу свободно редактировать черту и решение, опубликованные пользователем 4815162342 по адресу https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=d5763635625281acc066527207b290a7 чтобы переключиться на

 pub trait MapValue<'a, Out> {
    fn map_value<C>(amp;'a self, map_func: fn(C, Out), context: C);
}
 

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

 impl<'a, 'b: 'a> MapValue<'b, amp;'a i32> for i32 {
    fn map_value<C>(amp;'b self, map_func: fn(C, amp;'a i32), context: C) {
        let cpy = *self; // Something more useful happens here in the real code
        map_func(context, amp;cpy);
    }
}
 

https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=e0790588121ad569781b2ddfc9d33ee9

это не удается со следующей ошибкой

 14 |         map_func(context, amp;cpy);
   |         ------------------^^^^-
   |         |                 |
   |         |                 borrowed value does not live long enough
   |         argument requires that `cpy` is borrowed for `'a`
15 |     }
   |     - `cpy` dropped here while still borrowed
 

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

Комментарии:

1. Если вам разрешено изменять признак, вы можете поддерживать ссылки, введя в признак время жизни: play.rust-lang.org/…

2. @user4815162342 спасибо, что работает! к сожалению, это, похоже, не решило всех моих проблем, пожалуйста, просмотрите редактирование, если вам интересно