NEAR协议Rust抽奖合约开发出现结构体借用类型不匹配错误
错误根因
你遇到的类型错误来自多个代码问题:
- 你在获取抽奖实例时用了
&符号,使得lotto变量是&NearLotto类型的引用,而self.lotteries向量存储的是NearLotto结构体实例本身,最后一行尝试把引用赋值给存储结构体的位置,自然会出现类型不匹配。 - 你声明的是不可变引用,哪怕没有最后一行的赋值错误,前面修改
prize_pool、climate_pool等字段的操作也会编译失败。 - 额外的逻辑bug:你的资金分配计算写错了,当前
prize_pool和climate_pool都加了75%的用户付费,总和超过了100%,不符合你注释里写的75%进奖池、25%进气候基金的逻辑。
修复方案
直接获取对应抽奖实例的可变引用,修改操作会直接作用在向量存储的实例上,不需要额外赋值回向量,修改后的完整方法代码如下:
#[payable] pub fn enter_draw(&mut self, lotto_id:u32){ // 校验抽奖ID合法性,避免数组越界 assert!(lotto_id < self.lotteries.len() as u32, "Invalid lotto id"); // 获取可变引用,直接操作向量内的实例 let lotto = &mut self.lotteries[lotto_id as usize]; let attached = env::attached_deposit(); assert!(attached >= lotto.entry_fee, "Entry fee not enough"); assert!(lotto.entries.len() < MAX_ENTRIES, "Entries are full"); env::log(format!("money matches, add entry").as_bytes()); // 75%进奖池 lotto.prize_pool += (attached / 4) * 3; // 25%进气候基金 lotto.climate_pool += attached / 4; lotto.entries.push(&env::signer_account_id()); env::log(format!("{} Entering the lottery", env::signer_account_id()).as_bytes()); // 不需要额外赋值回向量,可变引用修改已经直接生效 }
改动点说明
- 新增了抽奖ID合法性校验,避免传入超过向量长度的ID导致程序panic
- 将原来的不可变引用改为
&mut可变引用,直接修改向量内存储的实例,不需要额外赋值 - 删掉了最后一行类型不匹配的赋值代码
- 修正了气候基金的资金分配计算逻辑
内容的提问来源于stack exchange,提问作者Joby Ingram-Dodd
相关产品推荐
相关产品推荐

