【发布时间】:2019-01-23 22:01:42
【问题描述】:
我已经构建了一个小结构,它包含一个伪 C 字符串 UnsafeMutablePointer。现在我想添加一种方法来获取字符串的长度,但是有些东西表现得很奇怪:
struct Char {
let value: CChar
init(_ char: CChar) {
self.value = char
}
}
extension Char: CustomStringConvertible {
var description: String {
return String(UnicodeScalar(UInt8(bitPattern: self.value)))
}
}
extension Char: Equatable {
public static func ==(lhs: Char, rhs: Char) -> Bool {
return lhs.value == rhs.value
}
}
struct CharPointer {
let pointer: UnsafeMutablePointer<Char>
init(_ string: String) {
let chars = string.cString(using: .utf8)!.map { Char($0) }
self.pointer = UnsafeMutablePointer(mutating: chars)
}
subscript(_ offset: Int) -> Char {
get { return self.pointer[offset] }
set { self.pointer[offset] = newValue }
}
var length: Int {
var ptr = self.pointer
while ptr.pointee != Char(0) {
ptr += 1
}
return ptr - self.pointer
}
}
let pointer = CharPointer("Hello World!")
print(pointer[0])
// print(pointer.length)
如果我不使用length 属性,一切都会正常工作,并且打印语句会打印一个“H”。但是如果我尝试访问pointer.length,它会打印一个换行符,尽管我在打印语句之后使用了该属性,并且长度为0。这是一个错误还是我犯了错误?
【问题讨论】:
-
UnsafeMutablePointer(mutating: chars)给你一个悬空指针,因为隐式参数转换产生的指针只在初始化程序调用期间有效——取消引用该指针会给你未定义的行为。真正的 Swift 应该禁止 UnsafePointer.init 参数的 inout-to-pointer 参数转换(我实际上正在研究实现它)。
标签: swift unsafe-pointers unsafemutablepointer