为何以UnsafeRawPointer传递结构体时需基于var而非let?
为什么Data.init(bytes:,count:)要求用var而非let变量取地址?
首先要明确:Swift里的&操作符,不管目标函数参数是UnsafeRawPointer还是inout,它的语义是创建一个临时的inout绑定——这个绑定规则要求被取地址的变量必须是可变的(var),哪怕函数本身不会通过指针修改内存。
具体到Data的初始化方法
虽然Data.init(bytes: UnsafeRawPointer, count: Int)接收的是不可变指针,但Swift的安全模型不会去验证函数内部是否真的会修改指针指向的内容。只要你用&取地址,编译器就会默认这个操作可能会修改变量,因此强制要求变量是var类型,否则就会抛出「Cannot pass immutable value as inout」的错误。
用let变量的替代方案
如果想用let定义的不可变变量生成Data,可以用withUnsafePointer(to:)显式获取不可变指针,这个API专门适配不可变变量的场景,编译器能确认不会修改内存,因此允许使用let:
let immutableCopy = instanceOfA let data = withUnsafePointer(to: immutableCopy) { ptr in Data(bytes: ptr, count: MemoryLayout.size(ofValue: instanceOfA)) }
核心原因总结
&操作符的inout绑定规则是根本:它要求变量可变,不管目标参数是否是不可变指针。withUnsafePointer(to:)是Swift提供的、针对不可变变量取指针的合法途径,绕过了&的var限制。
内容的提问来源于stack exchange,提问作者Theis Egeberg
相关产品推荐
相关产品推荐

