我的应用程序使用某种复杂的不可变数据结构,该结构以二进制文件编码。我需要在字节级别访问它,避免任何复制。通常,我将使用C或C
++指针算术和类型转换来访问和解释原始字节值。我想对Swift做同样的事情。
我发现以下作品:
class RawData {
var data: NSData!
init(rawData: NSData) {
data = rawData
}
func read<T>(byteLocation: Int) -> T {
let bytes = data.subdataWithRange(NSMakeRange(byteLocation, sizeof(T))).bytes
return UnsafePointer<T>(bytes).memory
}
func example_ReadAnIntAtByteLocation5() -> Int {
return read(5) as Int
}
}
但是,我不确定它的效率如何。每次我调用对象时都要做data.subdataWithRange
和NSMakeRange
分配对象,或者它们只是用于处理指针的语法糖吗?
在Swift中有更好的方法吗?
编辑:
我创建了一个小的Objective-C类,该类只封装了一个将指针偏移给定字节数的函数:
@implementation RawDataOffsetPointer
inline void* offsetPointer(void* ptr, int bytes){
return (char*)ptr + bytes;
}
@end
如果我在桥接标题中包含此类,则可以将read
方法更改为
func read<T>(byteLocation: Int) -> T {
let ptr = offsetPointer(data.bytes, CInt(byteLocation))
return UnsafePointer<T>(ptr).memory
}
这不会从我的缓冲区复制数据,也不会分配其他对象。
但是,如果可能的话,从Swift执行一些指针算术仍然是很好的。
如果您只想直接UnsafePointer<T>
进行操作,可以进行算术操作:
let oldPointer = UnsafePointer<()>
let newPointer = oldPointer + 10
您也可以像这样投射一个指针(UnsafePointer<()>
等效于void *
)
let castPointer = UnsafePointer<MyStruct>(oldPointer)
Rust通过限制智能指针的行为保障了编译时安全,不过仍需要对指针做一些额外的操作。 *const T和*mut T在Rust中被称为“裸指针”。它允许别名,允许用来写共享所有权的类型,甚至是内存安全的共享内存类型如:Rc<T>和Arc<T>,但是赋予你更多权利的同时意味着你需要担当更多的责任: 不能保证指向有效的内存,甚至不能保证是非空的 没有任何自动清除,所以需要手动管理资源 是普通旧式类型,也
本章开始讲解 Rust 中的 Unsafe 部分。 Unsafe 原始指针
正如在主要章节中所解释的,Pascal指针是一个地址,它是存储在单词中的数值。 因此,您可以像对数值一样对指针执行算术运算。 有四个算术运算符可用于指针:递增,递减,+和 - 。 为了理解指针运算,让我们考虑ptr是一个整数指针,它指向地址1000.假设32位整数,让我们对指针执行递增操作 - Inc(ptr); 现在,在上述操作之后, ptr将指向位置1004,因为每次ptr递增时,它将指向下
如你所知,指针是一个数值的地址; 因此,您可以像对数值一样对指针执行算术运算。 可以在指针上使用四个算术运算符:++, - ,+和 - 要理解指针运算,让我们考虑ptr是一个指向地址1000的整数指针。假设32位整数,让我们对指针执行以下算术运算 - ptr++ ptr将指向位置1004,因为每次ptr递增时,它将指向下一个整数。 此操作将指针移动到下一个存储器位置,而不会影响存储器位置的实际值
c中的指针是地址,它是一个数值。 因此,您可以像对数值一样对指针执行算术运算。 可以在指针上使用四个算术运算符:++, - ,+和 - 要理解指针运算,让我们考虑ptr是一个指向地址1000的整数指针。假设32位整数,让我们对指针执行以下算术运算 - ptr++ 在上述操作之后, ptr将指向位置1004,因为每次ptr递增时,它将指向下一个整数位置,该位置是当前位置旁边的4个字节。 此操作将指
Rust的内存安全依赖于强大的类型系统和编译时检测,不过它并不能适应所有的场景。 首先,所有的编程语言都需要跟外部的“不安全”接口打交道,调用外部库等,在“安全”的Rust下是无法实现的; 其次,“安全”的Rust无法高效表示复杂的数据结构,特别是数据结构内部有各种指针互相引用的时候;再次, 事实上还存在着一些操作,这些操作是安全的,但不能通过编译器的验证。 因此在安全的Rust背后,还需要uns