Rust中如何将Base64VecU8解码为Vec<u8>并与另一Vec<u8>合并?
Rust 合并 Vec 并传递给 function_call 的问题
我尝试将Base64VecU8解码后的结果与另一个JSON字符串转换的Vecfunction_call方法,但两种写法均报错:
原代码
pub fn decode_and_merge(&mut self, args: Base64VecU8) { // 这一步unwrap执行正常,但后续被覆盖未使用 let args_des: Vec<u8> = serde_json::to_string(&args).unwrap().into_bytes(); // 获取Base64VecU8解码后的Vec<u8> let args_des = args.0; // 尝试写法1:数组方式合并 let init_fn_args = [ Into::<Vec<u8>>::into(args_des)[..], serde_json::json!({ "market_creator_account_id": env::signer_account_id() }) .to_string() .into_bytes()[..], ]; let promise = Promise::new("cc".to_string()) .create_account() .deploy_contract(MARKET_CODE.to_vec()) .transfer(env::attached_deposit()) .function_call( "new".to_string(), init_fn_args, // 编译失败 0, GAS_FOR_CREATE_MARKET, ); // 尝试写法2:使用extend let init_fn_args = args_des.extend( serde_json::json!({ "market_creator_account_id": env::signer_account_id() }) .to_string() .into_bytes(), ); let promise = Promise::new("cc".to_string()) .create_account() .deploy_contract(MARKET_CODE.to_vec()) .transfer(env::attached_deposit()) .function_call( "new".to_string(), init_fn_args, // 编译失败 0, GAS_FOR_CREATE_MARKET, ); }
错误原因分析
写法1错误
编译错误:
error[E0308]: mismatched types --> src/contract.rs:69:47 | 69 | .function_call("new".to_string(), init_fn_args, 0, GAS_FOR_CREATE_MARKET); | ^^^^^^^^^^^^ expected struct `Vec`, found array `[[u8]; 2]` | = note: expected struct `Vec<u8>` found array `[[u8]; 2]`
你创建的是包含两个切片的数组[[u8];2],但function_call需要的是单个Vec<u8>实例,类型完全不匹配。此外代码中第一行的args_des被第二行覆盖,实际并未使用,属于冗余代码。
写法2错误
编译错误:
error[E0308]: mismatched types --> src/contract.rs:69:47 | 69 | .function_call("new".to_string(), init_fn_args, 0, GAS_FOR_CREATE_MARKET); | ^^^^^^^^^^^^ expected struct `Vec`, found `()` | = note: expected struct `Vec<u8>` found unit type `()`
Rust中Vec::extend方法是原地修改调用它的Vec实例,它的返回类型是()(单元类型)——因为它不需要返回新的Vec,而是直接在原Vec上追加元素。你把extend的返回值赋值给init_fn_args,自然得到的是(),不符合function_call的参数要求。
正确写法
方法1:原地扩展Vec
先获取解码后的Vec,再原地追加新的字节数据:
pub fn decode_and_merge(&mut self, args: Base64VecU8) { // 获取Base64解码后的Vec<u8> let mut init_fn_args = args.0; // 生成需要追加的字节数据 let extra_bytes = serde_json::json!({ "market_creator_account_id": env::signer_account_id() }) .to_string() .into_bytes(); // 原地扩展Vec init_fn_args.extend(extra_bytes); let promise = Promise::new("cc".to_string()) .create_account() .deploy_contract(MARKET_CODE.to_vec()) .transfer(env::attached_deposit()) .function_call( "new".to_string(), init_fn_args, 0, GAS_FOR_CREATE_MARKET, ); }
方法2:用迭代器合并生成新Vec
如果不想修改原Vec,可以通过迭代器的chain方法合并两个Vec,再收集为新的Vec:
pub fn decode_and_merge(&mut self, args: Base64VecU8) { let args_bytes = args.0; let extra_bytes = serde_json::json!({ "market_creator_account_id": env::signer_account_id() }) .to_string() .into_bytes(); // 合并两个Vec的迭代器,生成新Vec let init_fn_args = args_bytes.into_iter() .chain(extra_bytes.into_iter()) .collect::<Vec<u8>>(); let promise = Promise::new("cc".to_string()) .create_account() .deploy_contract(MARKET_CODE.to_vec()) .transfer(env::attached_deposit()) .function_call( "new".to_string(), init_fn_args, 0, GAS_FOR_CREATE_MARKET, ); }
内容的提问来源于stack exchange,提问作者Gus
相关产品推荐
相关产品推荐

