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作为参数。

如果您想要anIntvariables的大小,您可以将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 这里 。