【问题标题】:Type checking fails with optional value in Swift类型检查失败,Swift 中的可选值
【发布时间】:2019-05-20 17:32:26
【问题描述】:

当我有一个符合协议的类的可选值时,类型检查不会按预期工作。例如:

import Foundation

protocol MyProtocol { }

class MyClass: MyProtocol { }

let myClass: MyClass = MyClass()
let myClassType = type(of: myClass)

print("myClassType is MyClass.Type: \(myClassType is MyClass.Type)")
print("myClassType is MyProtocol.Type: \(myClassType is MyProtocol.Type)")

let myClassOpt: MyClass? = MyClass()
let myClassTypeOpt = type(of: myClassOpt)

print("myClassTypeOpt is MyClass?.Type: \(myClassTypeOpt is MyClass?.Type)")
print("myClassTypeOpt is MyProtocol?.Type: \(myClassTypeOpt is MyProtocol?.Type)")

输出:
myClassType 是 MyClass.Type: true
myClassType 是 MyProtocol.Type: true
myClassTypeOpt 是 MyClass?.Type: true
myClassTypeOpt 是 MyProtocol?.Type: false

最后一次类型检查的预期值为真,但结果为假。
在这种情况下,还有其他方法可以检查类型吗?

【问题讨论】:

  • 当你说“另一种检查类型的方法”时,是为了做什么?如果这确实按照您的想法工作,下一个代码块会是什么样子?这几乎肯定可以用另一种方式更好地解决。

标签: swift typechecking


【解决方案1】:

type(of: myClassOpt) 的结果不是创建该类型的变量。相反,它返回一个标识myClassOpt 类型的字符串。由于您已将myClassOpt 声明为MyClass? 类型,因此结果是一个类似Optional<MyClass> 的字符串。

所以是的,当你运行 myClassTypeOpt is MyProtocol?.Type 时,结果是 False。

【讨论】:

  • 所以无法检查可选值的类型?
  • 检查可选类型的最佳方法是使用if letguard let else 配置。在这种情况下,if let mine = myClassOpt as? MyClass {...。这就是我处理Any? 类型参数的方式。
【解决方案2】:

您可以使用if-let 首先unwrap optional 的值,然后检查其类型,而不是直接使用optional 来检查其类型,即

let myClassOpt: MyClass? = MyClass()

if let myClassOpt = myClassOpt {
    let myClassTypeOpt = type(of: myClassOpt)
    print("myClassTypeOpt is MyClass.Type: \(myClassTypeOpt is MyClass.Type)") //true
    print("myClassTypeOpt is MyProtocol.Type: \(myClassTypeOpt is MyProtocol.Type)") //true
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 2015-08-13
    • 2018-05-20
    • 2014-06-08
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多