Swift:如何使用sizeof?

时间:2014-07-09 20:05:09

标签: swift

为了在使用Swift时与C API集成,我需要使用sizeof函数。在C中,这很容易。在Swift中,我处于类型错误的迷宫中。

我有这段代码:

var anInt: Int = 5
var anIntSize: Int = sizeof(anInt)

第二行有错误"' NSNumber'不是' T.Type'"的子类型。为什么这样,我该如何解决?

5 个答案:

答案 0 :(得分:95)

针对Swift 3进行了更新

请注意,MemoryLayout<T>.size表示与C / Obj-C中的sizeof不同的内容。你可以阅读这个旧帖子https://devforums.apple.com/message/1086617#1086617

Swift使用泛型类型来明确表示编号在编译时是已知的。

总而言之,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

答案 1 :(得分:47)

使用sizeof如下:

let size = sizeof(Int)

sizeof使用类型作为参数。

如果您想要anInt变量的大小,可以将dynamicType字段传递给sizeof

像这样:

var anInt: Int = 5
var anIntSize: Int = sizeof(anInt.dynamicType)

或者更简单(user102008指出):

var anInt: Int = 5
var anIntSize: Int = sizeofValue(anInt)

答案 2 :(得分:23)

Swift 3现在有MemoryLayout.size(ofValue:),可以动态查找大小。

如果您使用MemoryLayout<Type>,则使用通用功能会产生意外结果传递协议类型的引用。这是因为 - 据我所知 - 然后编译器具有在编译时填充值所需的所有类型信息,这在查看函数调用时并不明显。然后,您将获得协议的大小,而不是当前值。

答案 3 :(得分:15)

在带有Swift 3 beta 6的Xcode 8中,没有函数sizeof()。但如果您愿意,可以根据自己的需要定义一个。这个新的sizeof函数与数组一起工作。使用旧的builtin 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函数的所有版本,以获取变量的大小并获得数据类型和数组的正确大小。

如果只定义第二个函数,那么sizeof(UInt8.self)和sizeof(Bool.self)将导致“8”。如果只定义前两个函数,那么sizeof(testArray)将产生“8”。

答案 4 :(得分:9)

Swift 4

从Xcode 9开始,现在有一个名为.bitWidth的属性,这为实例和整数类型提供了另一种写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

但将sizeof:替换为.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:转换为MemoryLayout here背后的原因。