You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法理解Solana序列化代码中&mut &mut可变引用及类型转换逻辑

问题1:为什么必须添加[..]

account.data.borrow_mut()返回的是RefMut类型的智能指针,它是RefCell的可变借用守卫,虽然实现了DerefMut可以隐式指向底层存储的字节切片,但Rust的泛型方法类型推导不会自动对智能指针做解引用转换。
[..]是Rust的全切片索引语法,作用是显式取出RefMut包裹的整个底层字节序列,直接得到原生的&mut [u8]类型可变切片,完全匹配序列化方法要求的字节容器类型。如果没有[..],传入的仍然是RefMut智能指针类型,无法满足参数要求。

问题2:两层&mut的类型转换逻辑

首先纠正一个误解:整个转换过程不会产生&[u32]类型,全程操作的都是u8类型的字节切片。
我们先看Borsh序列化方法的核心签名:

fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error>

它要求传入实现了Write trait的类型的可变引用,Rust标准库中只有&mut [u8]类型本身实现了Write trait,写操作会自动移动切片的起始指针,标记已写入的位置。
两层&mut的逻辑如下:

  • 第一步account.data.borrow_mut()[..]得到的是&mut [u8]类型的全量字节切片,我们临时称它为s
  • 序列化方法要求的参数是&mut W,其中W对应&mut [u8],所以需要对s再取一次可变引用,得到&mut &mut [u8]
  • Rust会自动对这个两层可变引用做解引用强制转换,匹配到Write trait的实现,完全符合方法的参数要求。

如果只传一层&mut,相当于直接把切片的所有权转移给序列化方法,方法写完后切片会变成指向未写入区域的切片,我们会丢失原来整个切片的引用。使用两层&mut只是把切片的可变借用传进去,原有的全量切片引用始终保持完整。

内容的提问来源于stack exchange,提问作者Craig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:36:02