如何在循环的前一次迭代中分配局部变量

How can a local variable be assigned in previous iteration of loop

只是一个问题,以便我更好地理解 Rust。

为什么会失败:

for event in rulesengine::RuleEvent::into_enum_iter()
{
  let mut event_stats: payloads::EventStats;
  event_stats.name = rulesengine::RuleEvent::to_string(&event);
  event_stats.event_count = event_counters.event_count[event as usize];
  event_stats.event_participant_count = event_counters.event_participant_count[event as usize];
  event_stats.event_trigger_count = event_counters.event_trigger_count[event as usize];
  rules_stats.event_stats.push(event_stats);
}

有:

error[E0382]: assign to part of moved value: `event_stats`
   --> src/motion.rs:317:37
    |
316 | ...                       let mut event_stats: payloads::EventStats;
    |                               --------------- move occurs because `event_stats` has type `payloads::EventStats`, which does not implement the `Copy` trait
317 | ...                       event_stats.name = rulesengine::RuleEvent::to_string(&event).clone();
    |                           ^^^^^^^^^^^^^^^^ value partially assigned here after move
...
323 | ...                   },
    |                       - value moved here, in previous iteration of loop

error: aborting due to previous error

当这有效时:

for event in rulesengine::RuleEvent::into_enum_iter()
{
  let name = rulesengine::RuleEvent::to_string(&event);
  let event_count = event_counters.event_count[event as usize];
  let event_participant_count = event_counters.event_participant_count[event as usize];
  let event_trigger_count = event_counters.event_trigger_count[event as usize];
  let event_stats = payloads::EventStats { name, event_count, event_participant_count, event_trigger_count };
  rules_stats.event_stats.push(event_stats);
}

甚至更好

for event in rulesengine::RuleEvent::into_enum_iter()
{
  let event_stats = payloads::EventStats
  {
    name: rulesengine::RuleEvent::to_string(&event),
    event_count: event_counters.event_count[event as usize],
    event_participant_count: event_counters.event_participant_count[event as usize],
    event_trigger_count: event_counters.event_trigger_count[event as usize],
  };
  rules_stats.event_stats.push(event_stats);
}

变量 event_stats 是可变的,但是是本地的。它不存在于要移动的“循环的上一次迭代”中。

我认为错误是对问题的误诊。过去有 compiler bugs 消息错误地将未初始化变量归咎于循环。也许这是另一个案例。


核心问题是您试图将字段分配给未初始化的值:

let mut event_stats: payloads::EventStats;
event_stats.name = ...;

您已声明 event_stats但尚未初始化。 Rust 不允许你分段初始化一个结构,至少在没有 a lot of extra juggling.

的情况下是这样。

您的两个工作解决方案都从结构文字创建 event_stats

let event_stats = payloads::EventStats { name: ..., ... };

这是初始化结构的正确方法。