当前位置: 首页>>编程示例 >>用法及示例精选 >>正文


Swift type(of:)用法及代码示例

函数

type(of:)

返回值的动态类型。

声明

func type<T, Metatype>(of value: T) -> Metatype

返回值

动态类型,它是一个元类型实例。

参数

value

要为其查找动态类型的值。

详述

您可以使用type(of:) 函数来查找值的动态类型,特别是当动态类型与静态类型不同时。值的static type 是该值的已知编译时类型。值的dynamic type 是该值在运行时的实际类型,可以是其具体类型的子类型。

在以下代码中,count 变量具有相同的静态和动态类型:Int。但是,当 count 传递给 printInfo(_:) 函数时,value 参数的静态类型为 Any(为参数声明的类型)和动态类型为 Int


func printInfo(_ value: Any) {
    let t = type(of: value)
    print("'\(value)' of type '\(t)'")
}


let count: Int = 5
printInfo(count)
// '5' of type 'Int'

type(of:) 返回的动态类型是类、结构、枚举或其他非协议类型 Tconcrete metatype ( T.Type ),或协议或协议组合的 existential metatype ( P.Type ) P 。当传递给 type(of:) 的值的静态类型被限制为类或协议时,您可以使用该元类型来访问类或协议的初始化程序或其他静态成员。

例如,以下示例中作为value 传递给printSmileyInfo(_:) 函数的参数是Smiley 类或其子类之一的实例。该函数使用 type(of:) 来查找 value 的动态类型,它本身就是 Smiley.Type 元类型的一个实例。


class Smiley {
    class var text: String {
        return ":)"
    }
}


class EmojiSmiley: Smiley {
     override class var text: String {
        return "😀"
    }
}


func printSmileyInfo(_ value: Smiley) {
    let smileyType = type(of: value)
    print("Smile!", smileyType.text)
}


let emojiSmiley = EmojiSmiley()
printSmileyInfo(emojiSmiley)
// Smile! 😀

在此示例中,访问 smileyType 元类型的 text 属性将从 EmojiSmiley 子类而不是 Smiley 类的原始定义中检索覆盖的值。

在通用上下文中查找动态类型

通常,您不需要了解具体元类型和存在元类型之间的区别,但调用 type(of:) 可能会在类型参数绑定到协议的泛型上下文中产生意外结果。在这种情况下,泛型参数 T 绑定到协议 P ,类型参数在泛型函数的主体中不是静态已知的协议类型。因此,type(of:) 只能生成具体的元类型 P.Protocol

以下示例定义了一个 printGenericInfo(_:) 函数,该函数采用通用参数并声明 String 类型与新协议 P 的一致性。当使用具有 P 作为其静态类型的字符串调用 printGenericInfo(_:) 时,对 type(of:) 的调用将返回 P.self 而不是 String.self(参数内的动态类型)。


func printGenericInfo<T>(_ value: T) {
    let t = type(of: value)
    print("'\(value)' of type '\(t)'")
}


protocol P {}
extension String: P {}


let stringAsP: P = "Hello!"
printGenericInfo(stringAsP)
// 'Hello!' of type 'P'

出现此意外结果是因为在 printGenericInfo(_:) 中对 type(of: value) 的调用必须返回作为 T.Type 实例的元类型,但 String.self(预期的动态类型)不是 P.Type(具体元类型)的实例value )。要在此通用上下文中获取 value 中的动态类型,请在调用 type(of:) 时将参数强制转换为 Any


func betterPrintGenericInfo<T>(_ value: T) {
    let t = type(of: value as Any)
    print("'\(value)' of type '\(t)'")
}


betterPrintGenericInfo(stringAsP)
// 'Hello!' of type 'String'

可用版本

iOS 8.0+, iPadOS 8.0+, macOS 10.10+, Mac Catalyst 13.0+, tvOS 9.0+, watchOS 2.0+

相关用法


注:本文由纯净天空筛选整理自apple.com大神的英文原创作品 type(of:)。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。