作为协议实例的变量与类实例的变量的基础类型不同吗?

Noe*_*oel 3 generics swift swift-protocols

鉴于基础类型是相同的,我期望test2true,而不是false

protocol Foo {}
class Bar: NSObject, Foo {}
class Test {
    func testCompare() {
        let b = Bar()
        let test1 = compare(expected: Bar.self, actual: b)
        let c: Foo = b
        let test2 = compare(expected: Bar.self, actual: c)
        /*
         (lldb) p expected
         (@thick NSObject.Type) $R0 = SpokestackTests.Bar
         (lldb) p type(of: actual).self
         (SpokestackTests.Foo.Type) $R2 = SpokestackTests.Bar
        */
        print(test1, test2) // true false
    }
    
    func compare<T>(expected: NSObject.Type, actual: T) -> Bool {
        return expected == type(of: actual).self
    }
}
Run Code Online (Sandbox Code Playgroud)

这是由于类的具体元类型与协议实例的存在元类型之间的差异造成的吗?

gch*_*ita 6

查看type(of:)函数的文档后,我们可以将最后一段改写为如下所示:

type(of: value) 出现这种意外结果是因为对inside的调用必须返回一个元类型,该元类型是参数 ( )的静态类型的compare(expected:actual:)实例。要获取此通用上下文中的动态类型内部值,请在调用 type(of:) 时将参数强制转换为 Any。T.TypeactualFoo.self

或者只是将compare(expected:actual:)函数更改为使用Any类型而不是泛型:

private func compare(expected: NSObject.Type, actual: Any) -> Bool {
    return expected == type(of: actual).self
}
Run Code Online (Sandbox Code Playgroud)

更新:更好的是,您可以在评论中使用@Jessy 建议

func compare<Expected: Foundation.NSObject>(expected: Expected.Type, actual: Any) -> Bool {
    return type(of: actual) is Expected.Type
}
Run Code Online (Sandbox Code Playgroud)

  • 可能更好地表达为:```funccompare&lt;Expected: Foundation.NSObject&gt;(expected_: Expected.Type,actual:Any) -&gt; Bool { type(of:actual) is Expected.Type } ``` (3认同)