首页 > 解决方案 > 如何避免为 MutexGuard 接口移动可能未初始化的变量?

问题描述

对于以下代码:

  let conversation_model =
    if lsm { CONVMODEL.lock().await } else {
      conv_model_loader()
    };

CONVMODEL.lock().awaitMutexGuard<T>而且conv_model_loader()只是T

我需要这两个通用接口,所以我不能在两种情况下复制粘贴我的代码,因为它只会与这种类型不同,其他任何东西都是一样的。

编辑:

有代码......(至少我试图做的)

  let (locked, loaded);  // pun not intended
  if lsm {
    locked = CONVMODEL.lock().await;
  } else {
    loaded = conv_model_loader();
  };
  let mut chat_context = CHAT_CONTEXT.lock().await;
  task::spawn_blocking(move || {
    let conversation_model = if lsm { &*locked } else { &loaded };

但我失败了,因为

use of possibly-uninitialized variable: `locked`\nuse of possibly-uninitialized `locked`

所以问题实际上是如何MutexGuard使用接口&T但在内部使用spawn_blocking#[async_recursion]

编辑:

  let (mut locked, mut loaded) = (None, None);
  if lsm {
    locked = Some( CONVMODEL.lock().await );
  } else {
    loaded = Some( conv_model_loader() );
  };
  let mut chat_context = CHAT_CONTEXT.lock().await;
  task::spawn_blocking(move || {
    let (lock, load);
    let conversation_model =
      if lsm {
        lock = locked.unwrap();
        &*lock
      } else {
        load = loaded.unwrap();
        &load
      };

以下代码正在运行,但实际上非常难看 XD(我想知道是否可以简化此代码)

标签: rusttokio

解决方案


您可以&mut T从两者中提取并使用它。像下面这样的东西应该可以工作:

let (locked, loaded);  // pun not intended
let conversation_model = if lsm {
    locked = CONVMODEL.lock().await;
    &mut *locked
} else {
    loaded = conv_model_loader();
    &mut loaded
};

推荐阅读