Swift:如何使用sizeof?
为了在使用Swift时与C API集成,我需要使用sizeof函数。 在C中,这很容易。 在Swift中,我处在一个错误的迷宫中。
我有这个代码:
var anInt: Int = 5 var anIntSize: Int = sizeof(anInt)
第二行有错误“'NSNumber'不是”T.Type“的子types。 为什么是这个,如何解决?
使用sizeof如下:
let size = sizeof(Int)
sizeof
使用types作为参数。
如果您想要anInt
variables的大小,您可以将dynamicType
字段传递给sizeof
。
像这样:
var anInt: Int = 5 var anIntSize: Int = sizeof(anInt.dynamicType)
或者更简单地(由user102008指出):
var anInt: Int = 5 var anIntSize: Int = sizeofValue(anInt)
更新了Swift 3
请注意, MemoryLayout<T>.size
含义与C / Obj-C中的sizeof
不同。 你可以阅读这个旧的线程https://devforums.apple.com/message/1086617#1086617
Swift使用generics来明确编译时已知的数字。
总而言之, MemoryLayout<Type>.size
是单个实例所需的空间,而MemoryLayout<Type>.stride
是连续数组中连续元素之间的距离。 在Swift中的MemoryLayout<Type>.stride
与C / Obj-C中的sizeof(type)
相同。
举一个更具体的例子:
struct Foo { let x: Int let y: Bool } MemoryLayout<Int>.size // returns 8 on 64-bit MemoryLayout<Bool>.size // returns 1 MemoryLayout<Foo>.size // returns 9 MemoryLayout<Foo>.stride // returns 16 because of alignment requirements MemoryLayout<Foo>.alignment // returns 8, addresses must be multiples of 8
在使用Swift 3 beta 6的Xcode 8中,没有函数sizeof()。 但是,如果你想,你可以为你的需求定义一个。 这个新的sizeof函数按照预期的方式工作。 这是旧的内置sizeof函数不可能的。
let bb: UInt8 = 1 let dd: Double = 1.23456 func sizeof <T> (_ : T.Type) -> Int { return (MemoryLayout<T>.size) } func sizeof <T> (_ : T) -> Int { return (MemoryLayout<T>.size) } func sizeof <T> (_ value : [T]) -> Int { return (MemoryLayout<T>.size * value.count) } sizeof(UInt8.self) // 1 sizeof(Bool.self) // 1 sizeof(Double.self) // 8 sizeof(dd) // 8 sizeof(bb) // 1 var testArray: [Int32] = [1,2,3,4] var arrayLength = sizeof(testArray) // 16
您需要sizeof函数的所有版本来获取variables的大小,并获取数据types和数组的正确大小。
如果你只定义第二个函数,那么sizeof(UInt8.self)和sizeof(Bool.self)将会导致“8”。 如果只定义前两个函数,那么sizeof(testArray)将导致“8”。
Swift 3现在有MemoryLayout.size(ofValue:)
,它可以dynamic查找大小。
使用一个通用的函数,反过来使用MemoryLayout<Type>
将有意想不到的结果,如果你通过它的协议types的引用。 这是因为 – 据我所知 – 编译器在编译时需要填写所有的types信息,这在查看函数调用时并不明显。
斯威夫特4
从Xcode 9开始,现在有一个名为.bitWidth
的属性,它为实例和整数types提供了另一种编写sizeof:
函数的方法:
func sizeof<T:FixedWidthInteger>(_ int:T) -> Int { return int.bitWidth/UInt8.bitWidth } func sizeof<T:FixedWidthInteger>(_ intType:T.Type) -> Int { return intType.bitWidth/UInt8.bitWidth } sizeof(UInt16.self) // 2 sizeof(20) // 8
但是,将一致性replace为sizeof:
with .byteWidth
会更有意义:
extension FixedWidthInteger { var byteWidth:Int { return self.bitWidth/UInt8.bitWidth } static var byteWidth:Int { return Self.bitWidth/UInt8.bitWidth } } 1.byteWidth // 8 UInt32.byteWidth // 4
很容易明白为什么sizeof:
被认为是模棱两可的,但我不确定将它埋在MemoryLayout中是否正确。 看到sizeof:
转移背后的原因sizeof:
到MemoryLayout
这里 。