苹果文档中的Swift代码编译报错:无法将不可变值作为inout参数传递——‘pointee’是只读属性
Let's break down the problem first: The error pops up because you're using withUnsafePointer(to: &ss) which gives you an immutable pointer (UnsafePointer<sockaddr_storage>). When you rebound this to AddrType, you still end up with an immutable UnsafePointer<AddrType>—its pointee property is read-only, so you can't pass &$0.pointee as an inout argument to your body closure (which expects a mutable reference).
The Fix: Use a Mutable Pointer
To fix this, you need to work with a mutable pointer to your sockaddr_storage variable. Here's the corrected version of your extension:
import Foundation import Darwin extension sockaddr_storage { //... static func fromSockAddr<AddrType, ReturnType>(_ body: (_ sax: inout AddrType) throws -> ReturnType) rethrows -> (ReturnType, sockaddr_storage) { precondition(MemoryLayout<AddrType>.size <= MemoryLayout<sockaddr_storage>.size) var ss = sockaddr_storage() let result = try withUnsafeMutablePointer(to: &ss) { // Switch to mutable pointer try $0.withMemoryRebound(to: AddrType.self, capacity: 1) { mutableAddrPtr in try body(&mutableAddrPtr.pointee) // Now valid: mutable pointer's pointee can be passed as inout } } return (result, ss) } }
Key Changes Explained:
- Replaced
withUnsafePointer(to: &ss)withwithUnsafeMutablePointer(to: &ss): This gives us anUnsafeMutablePointer<sockaddr_storage>, which lets us modify the underlying memory of ourssvariable. - After rebounding, we get an
UnsafeMutablePointer<AddrType>. Thepointeeof a mutable pointer can be referenced with&to create a validinoutargument, which matches exactly what yourbodyclosure expects.
This approach stays safe because we fully own the sockaddr_storage variable (var ss) throughout the scope, so modifying its memory via the mutable pointer complies with Swift's memory safety rules.
内容的提问来源于stack exchange,提问作者shallowThought

