gpt4 book ai didi

swift - swift 中 Any.Type 的大小

转载 作者:搜寻专家 更新时间:2023-10-31 19:36:24 25 4
gpt4 key购买 nike

我在获取声明为 Any.Type 的变量的大小时遇到​​了问题

请参阅以下 Playground 代码:

我有这个功能:

func genericSizeMe<T> (_ : T.Type) -> Int
{
return MemoryLayout<T>.size
}

我是这样运行的:

let size1 = genericSizeMe(UInt32.self) // 4
let size2 = genericSizeMe(UInt16.self) // 2

var type1: UInt32.Type = UInt32.self
let size3 = genericSizeMe(type1) // 4

var type2: UInt16.Type = UInt16.self
let size4 = genericSizeMe(type2) // 2


var type3: Any.Type = UInt32.self
let size5 = genericSizeMe(type3) //ERROR

这给出了错误:

/*

Playground execution failed:

error: MyPlayground.playground:14:13: error: cannot invoke 'genericSizeMe' with an argument list of type '(Any.Type)'
let size5 = genericSizeMe(type3)
^

MyPlayground.playground:14:13: note: expected an argument list of type '(T.Type)'
let size5 = genericSizeMe(type3)
^

*/

如何(如果可能)解决这个问题?我想要实现的是拥有一个类型数组,并获取每种类型的大小。像这样:

[UInt32.self, UInt8.self]

然后遍历数组并打印分配每种类型所需的字节大小。


如果更简单,我也可以接受在获取大小之前实际创建每种类型的实例。

最佳答案

您在使用通用函数时遇到的问题是 when a generic placeholder T is a protocol type P, T.Type is not P.Type; it's P.Protocol .

因此,您不能将 Any.Type 传递给 T.Type 参数(尽管 Any 在技术上不是协议(protocol),它是一个特殊的内置类型;在大多数情况下它具有协议(protocol)的语义)。您需要传递表示具体类型的元类型。

因此,一种解决方案是为元类型构建类型删除包装器,如 Check whether Swift object is an instance of a given metatype 所示。 :

struct AnyType {

let base: Any.Type
private let _memorySize: () -> Int
private let _memoryStride: () -> Int
private let _memoryAlignment: () -> Int

var memorySize: Int { return _memorySize() }
var memoryStride: Int { return _memoryStride() }
var memoryAlignment: Int { return _memoryAlignment() }

/// Creates a new AnyType wrapper from a given metatype.
/// The passed metatype's value **must** match its static value,
/// i.e `T.self == base` must be `true`.
init<T>(_ base: T.Type) {
precondition(T.self == base, """
The static value \(T.self) and dynamic value \(base) of the \
passed metatype do not match
"""
)
self.base = T.self
self._memorySize = { MemoryLayout<T>.size }
self._memoryStride = { MemoryLayout<T>.stride }
self._memoryAlignment = { MemoryLayout<T>.alignment }
}
}

然后你可以像这样使用它:

struct S {
var i: Int
var b: Bool
}

let types = [AnyType(UInt32.self), AnyType(UInt8.self), AnyType(S.self)]

for type in types {
print("Size of \(type.base): \(type.memorySize)")
print("Stride of \(type.base): \(type.memoryStride)")
print("Alignment of \(type.base): \(type.memoryAlignment)")
print()
}

// Size of UInt32: 4
// Stride of UInt32: 4
// Alignment of UInt32: 4
//
// Size of UInt8: 1
// Stride of UInt8: 1
// Alignment of UInt8: 1
//
// Size of S: 9
// Stride of S: 16
// Alignment of S: 8

关于swift - swift 中 Any.Type 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47922374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com