【问题标题】:Swift - check if two objects are of same type or superclass-typeSwift - 检查两个对象是否属于相同类型或超类类型
【发布时间】:2021-03-06 11:48:38
【问题描述】:

我想检查两个对象是否属于 - 或属于 - 同一个超类。

class myClass {}
class mySubclass: myClass {}

let myObject = myClass()
let myOtherObject = myClass()
let mySubclassedObject = mySubclass()

我知道我可以这样检查类型:

type(of: myObject) == myClass.self                // true
type(of: myObject) == type(of: myOtherObject)     // true

type(of: mySubclassedObject) == myClass.self      // false

最后一条语句返回 false,因为 type(of: <T>) 显然返回了对象的最终类。

类型检查的另一种方法是is 关键字:

mySubclassedObject is mySubclass     // true
mySubclassedObject is myClass        // true 

这里两个语句都为真,因为is 关键字显然是在考虑超类。但是我不能这样做是像这样比较两个对象的类型:

myOtherObject is myObject   // Use of undeclared type 'myObject'

我需要得到这样的结果:

myObject is myOtherObject        // true 
mySubclassedObject is myObject   // true
myObject is mySubclassedObject   // false

我希望找到类似.isSubclassOf 的东西,但这似乎在 Swift 中不可用。那么我怎样才能得到我想要的结果呢?

【问题讨论】:

    标签: swift types subclass


    【解决方案1】:

    一种方法是尝试这样的泛型

    func isObject<P>(_ object: Any, ofType other: P) -> Bool {
        object is P
    }
    
    isObject(myObject, ofType: myOtherObject)           //true
    isObject(mySubclassedObject, ofType: myObject)      //true
    isObject(myObject, ofType: mySubclassedObject)      //false
    

    【讨论】:

      【解决方案2】:

      我想你问的是与 .Net 平台上的 Type.IsSubclassOf(Type) 相同的功能

      他们的医生说

      方法Type.IsSubclassOf(Type)如果当前Type返回true 源自 c;否则为假。如果 c,此方法也返回 false 和当前类型相等。来源:microsoft doc

      Swift 具有类型检查操作 (is) 来检查实例是否属于某个子类类型,但如果两者是相同类型,则返回 true。这种行为使其与 .Net Type.IsSubclassOf(Type) 方法不同。 source

      解决方案是开发一个行为类似于Type.IsSubclassOf(Type) 的自定义函数。

      Any、AnyClass 和 AnyObject 不能有扩展,所以最好的方法是创建一个全局函数:

      func type<T: AnyObject >(_ object: AnyObject, isSubclassOf toto: T) -> Bool {
          if object is T {
              if Swift.type(of: object) === Swift.type(of: myOtherObject) {
                  return false
              } else {
                  return true
              }
          } else {
              return false
          }
      }
      

      上面的函数将通过以下测试:

      // MARK: - --- UnitTests ---
      import XCTest
      
      class TypeIsSubclassOfTests: XCTestCase {
          func testSubclass() {
              XCTAssertFalse(type(myObject, isSubclassOf: myOtherObject))
              XCTAssertFalse(type(myOtherObject, isSubclassOf: myObject))
              XCTAssertTrue(type(mySubclassedObject, isSubclassOf: myObject))
              XCTAssertFalse(type(myObject, isSubclassOf: mySubclassedObject))
          }
      }
      

      该函数的用法如下:

      if type(object1, isSubclassOf: object2) {
          debugPrint("object1 is a class which subclass from object2 class")
      } else {
          debugPrint("object1 is the same class as object2 or is not a subclass of object2 class")
      }
      

      【讨论】:

        【解决方案3】:

        is 运算符需要 rhs(右侧)的类型,而不是实例/对象。

        Swift 的约定是类名不能以小写字母开头。如果我按照约定重写你的代码,用类名替换对象类型,我会得到你期望的结果:

        class MyClass {}
        class MySubclass: MyClass {}
        
        let myObject = MyClass()
        let myOtherObject = MyClass()
        let mySubclassedObject = MySubclass()
        
        type(of: myObject) == MyClass.self                // true
        type(of: myObject) == type(of: myOtherObject)     // true
        
        type(of: mySubclassedObject) == MyClass.self      // false
        
        mySubclassedObject is MySubclass     // true
        mySubclassedObject is MyClass        // true
        
        myOtherObject is MyClass
        
        myObject is MyClass        // true
        mySubclassedObject is MyClass   // true
        myObject is MySubclass   // false
        

        is 运算符需要 rhs 上的类型,而不是对象。

        【讨论】:

          猜你喜欢
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-14
          • 1970-01-01
          • 1970-01-01
          • 2022-01-25
          相关资源
          最近更新 更多