Nano Hash - криптовалюты, майнинг, программирование

Почему заимствование из `HashMap::get` не заканчивается, когда функция возвращается?

Вот эмуляция моей проблемы, когда заимствование заканчивается слишком поздно

use std::collections::HashMap;

struct Item {
    capacity: u64
}

struct Petrol {
    name: String,
    fuel: HashMap<&'static str, Item>
}

fn buy_gaz(p: &mut Petrol) {
   match p.fuel.get("gaz") {
      Some(gaz) => {
        fire_petrol(p); 
      }
      None => ()
   }
}

fn fire_petrol(p: &mut Petrol) {
    println!("Boom!");
    p.fuel.remove("gaz");
    p.fuel.remove("benzin");
}

fn main() {
    let mut bt = Petrol {
        name: "Britii Petrovich".to_string(),
        fuel: HashMap::new()
    };

    bt.fuel.insert("gaz", Item { capacity: 1000 });
    bt.fuel.insert("benzin", Item { capacity: 5000 });

    buy_gaz(&mut bt);
}

При компиляции получаю:

note: previous borrow of `p.fuel` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `p.fuel` until the borrow ends
match p.fuel.get("gaz") {
      ^~~~~~

Почему заимствование заканчивается так поздно, а не при выходе из HashMap::get? Как исправить мой случай?

PS: я отредактировал свой первый пост для добавления структуры в HashMap, потому что приведенное ниже решение работало для простых типов (я думаю, с чертой Clone по умолчанию), но не работает для пользовательских структур

10.04.2015

Ответы:


1

Если вы посмотрите на документацию HashMap::get, вы можно видеть, что он возвращает Option<&V>. Ссылка на карту позволяет выполнять доступ к хэш-карте без копирования. Недостатком является то, что пока у вас есть ссылка, вы не можете изменить хэш-карту, поскольку это может сделать вашу ссылку недействительной.

Ветвь Some(gaz) приводит к тому, что привязка gaz имеет тип &u64, где ссылка указывает на вашу хэш-карту. Если вы измените это на Some(&gaz), вы получите копию значения вместо ссылки и можете изменить хэш-карту даже внутри этой ветки.

Минимальный пример в манеже

10.04.2015
  • Извините, но у меня более сложная структура, что делать в таком случае Play.Rust? 10.04.2015
  • Я бы сделал свою структуру копируемой, добавив #[derive(Copy)] перед определением структуры: is.gd/nrBnMk 10.04.2015
  • если у вас действительно некопируемая структура, вы можете использовать remove вместо get, что удаляет значение с карты и возвращает его 10.04.2015
  • Я не хочу копировать свою структуру(. Но если я использую remove, я меняю HashMap , и я просто хочу получить значение и ничего более. И это значение я не могу скопировать. Только такие решения существуют? 10.04.2015
  • если вы получите значение, вы не можете изменять хэш-карту. поэтому вы не можете вызвать функцию, которая хочет &mut self. Скорее всего, вы сможете обойти свою проблему. но поскольку fire_petrol не использует gaz, вы можете просто вызвать fire_petrol после совпадения и вместо этого ветвь None=>() будет None=>return 10.04.2015
  • Хорошо, спасибо, это не то, что я хочу, но я понял концепцию 10.04.2015
  • Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..