Как изменить карту хранилища, в которой значение является перечислением?

#rust #substrate

Вопрос:

вот моя карта хранения:

 #[pallet::getter(fn hotel_status)]  /// Keeps track of what accounts own what Kitty.  pub(super) type HotelStatuslt;T: Configgt; = StorageMaplt;  _,  Twox64Concat,  T::AccountId,  Gender,  gt;;  

Я хочу использовать try_mutate либо для изменения пола, потому что идентификатор учетной записи уже существует на карте, либо для вставки новой записи. Вот полная внешняя:

 #[pallet::weight(0)]  pub fn activate_hotel(  origin: OriginForlt;Tgt;,  hotel: T::AccountId,  ) -gt; DispatchResult {  let sender = ensure_signed(origin)?;  log::info!("signer ID: {:?}.", sender);  let hotel_status = lt;HotelStatuslt;Tgt;gt;::get(amp;hotel);  ensure!(hotel_status == Some(Gender::Active), lt;Errorlt;Tgt;gt;::HotelAlreadyActive);  lt;HotelStatuslt;Tgt;gt;::try_mutate(hotel, |status| {  status = Gender::Active;  }).map_err(|_| lt;HotelStatuslt;Tgt;gt;::insert(hotel, Gender::Active));    Ok(())  }  

ошибка, которую я получаю, заключается в следующем

 mismatched types expected mutable reference, found enum `pallet::Gender` note: expected mutable reference `amp;mut std::option::Optionlt;pallet::Gendergt;`  found enum `pallet::Gender`rustc(E0308) lib.rs(297, 14): expected mutable reference, found enum `pallet::Gender`  

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

Ответ №1:

  • Gender::Active является перечислением
  • status является amp;mut Optionlt;pallet::Gendergt;

Вы не можете назначить Gender::Active status , потому что существуют разные типы. Вот что говорит вам сообщение об ошибке:

 expected mutable reference `amp;mut std::option::Optionlt;pallet::Gendergt;`  found enum `pallet::Gender`rustc(E0308)  

Чтобы изменить значение, стоящее за ссылкой, вам нужно (в данном случае) разыменовать его с * помощью оператора. *status тип есть Optionlt;pallet::Gendergt; . Вам нужно обернуть Gender::Active в Some вариант , прежде чем назначать его *status , так Some(Gender::Active) как тип также Optionlt;pallet::Gendergt; есть .

 try_mutate(hotel, |status| {  *status = Some(Gender::Active);  Ok(()) }  

Ok(()) требуется, потому что закрытие должно возвращать Result

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

1. Извините @Jerboas86, но не могли бы вы также указать, как обеспечить обработку в случае ошибки? пример из учебника, похоже, применим только для Vecs cannot infer type for type parameter 'E' declared on the associated function 'try_mutate'

2. try_mutate::lt;_, _, (), _gt;(hotel,... если вы укажете с помощью turbofish anotation, это сработает ?