#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, это сработает ?