Swift:如何使用sizeof?

use*_*430 47 swift

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

我有这个代码:

var anInt: Int = 5
var anIntSize: Int = sizeof(anInt)
Run Code Online (Sandbox Code Playgroud)

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

Ray*_*Fix 99

针对Swift 3进行了更新

注意这MemoryLayout<T>.size意味着与sizeofC/Obj-C 不同的东西.你可以阅读这个旧帖子 https://devforums.apple.com/message/1086617#1086617

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

总而言之,MemoryLayout<Type>.size单个实例所需的空间MemoryLayout<Type>.stride是连续数组中连续元素之间的距离. MemoryLayout<Type>.stride在Swift中与sizeof(type)在C/Obj-C中相同.

举一个更具体的例子:

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
Run Code Online (Sandbox Code Playgroud)

  • 哇,与 sizeof 过去所做的相比,这是一个非常严重的变化。当我们的团队过渡到 Swift 3 时导致了一些错误。 (2认同)

wbe*_*ett 48

使用sizeof如下:

let size = sizeof(Int)
Run Code Online (Sandbox Code Playgroud)

sizeof 使用类型作为参数.

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

像这样:

var anInt: Int = 5
var anIntSize: Int = sizeof(anInt.dynamicType)
Run Code Online (Sandbox Code Playgroud)

或者更简单(user102008指出):

var anInt: Int = 5
var anIntSize: Int = sizeofValue(anInt)
Run Code Online (Sandbox Code Playgroud)

  • 或者`让anIntSize = sizeofValue(anInt)` (9认同)

And*_*eas 23

Swift 3现在MemoryLayout.size(ofValue:)可以动态查看大小.

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


j.s*_*com 16

在带有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
Run Code Online (Sandbox Code Playgroud)

您需要sizeof函数的所有版本,以获取变量的大小并获得数据类型和数组的正确大小.

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

  • 我不推荐这个.它为调用者提供了动态查找类型的错觉,而实际上是静态地执行它.如果传入协议类型的引用,您将获得协议的大小,而不是当前值. (3认同)

ske*_*ech 9

斯威夫特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
Run Code Online (Sandbox Code Playgroud)

但它将使一致性来代替更有意义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
Run Code Online (Sandbox Code Playgroud)

很容易sizeof:理解为什么我的想法含糊不清但我不确定将它埋在MemoryLayout中是正确的做法.看看转移sizeof:MemoryLayout 这里背后的原因.

  • 这使事情变得更简单,更容易理解.谢谢Apple!(讽刺)..... (4认同)