Swift - 检查两个对象是否属于同一类型或超类类型
Swift - check if two objects are of same type or superclass-type
我想检查两个对象是否属于 - 或者属于 - 同一个超级class。
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
最后的说法returns为假,因为type(of: <T>)
显然returns对象的最终class.
类型检查的另一种方法是 is
关键字:
mySubclassedObject is mySubclass // true
mySubclassedObject is myClass // true
此处两个语句的计算结果均为真,因为 is
关键字显然考虑了 superclass。但是我不能那样做的是像这样比较两个对象的类型:
myOtherObject is myObject // Use of undeclared type 'myObject'
我需要得到这样的结果:
myObject is myOtherObject // true
mySubclassedObject is myObject // true
myObject is mySubclassedObject // false
我希望找到类似 .isSubclassOf
的东西,但在 Swift 中似乎找不到。那么我怎样才能得到我想要的结果呢?
一种方法可能是尝试这样的泛型
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
is
运算符需要右手边的类型(右侧),而不是 instance/object。
Swift 惯例是 class 名称不能以小写字母开头。如果我按照惯例重写您的代码,将对象类型替换为 class 名称,我将得到您期望的结果:
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 上的类型,而不是对象。
我想您问的是与 .Net 平台上的 Type.IsSubclassOf(Type) 相同的功能
他们的医生说
the method Type.IsSubclassOf(Type)
return true if the current Type
derives from c; otherwise, false. This method also returns false if c
and the current Type are equal. source: microsoft doc
Swift 具有类型检查操作(是)以检查实例是否属于某个子类类型,但它 returns 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")
}
我想检查两个对象是否属于 - 或者属于 - 同一个超级class。
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
最后的说法returns为假,因为type(of: <T>)
显然returns对象的最终class.
类型检查的另一种方法是 is
关键字:
mySubclassedObject is mySubclass // true
mySubclassedObject is myClass // true
此处两个语句的计算结果均为真,因为 is
关键字显然考虑了 superclass。但是我不能那样做的是像这样比较两个对象的类型:
myOtherObject is myObject // Use of undeclared type 'myObject'
我需要得到这样的结果:
myObject is myOtherObject // true
mySubclassedObject is myObject // true
myObject is mySubclassedObject // false
我希望找到类似 .isSubclassOf
的东西,但在 Swift 中似乎找不到。那么我怎样才能得到我想要的结果呢?
一种方法可能是尝试这样的泛型
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
is
运算符需要右手边的类型(右侧),而不是 instance/object。
Swift 惯例是 class 名称不能以小写字母开头。如果我按照惯例重写您的代码,将对象类型替换为 class 名称,我将得到您期望的结果:
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 上的类型,而不是对象。
我想您问的是与 .Net 平台上的 Type.IsSubclassOf(Type) 相同的功能
他们的医生说
the method
Type.IsSubclassOf(Type)
return true if the current Type derives from c; otherwise, false. This method also returns false if c and the current Type are equal. source: microsoft doc
Swift 具有类型检查操作(是)以检查实例是否属于某个子类类型,但它 returns 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")
}