我有一个由AnyObject组成的数组。我想遍历它,找到所有数组实例的元素。

我怎么能检查如果一个对象是一个给定的类型在Swift?


当前回答

是吗?不会总是给出预期的结果,因为as并不测试数据类型是否为特定类型,而只测试数据类型是否可以转换为或表示为特定类型。

以下面的代码为例:

func handleError ( error: Error ) {
    if let nsError = error as? NSError {

每个符合Error协议的数据类型都可以转换为NSError对象,所以这总是会成功。但这并不意味着error实际上是一个NSError对象或它的子类。

正确的类型检查应该是:

func handleError ( error: Error ) {
    if type(of: error) == NSError.self {

但是,这只检查确切的类型。如果你还想包含NSError的子类,你应该使用:

func handleError ( error: Error ) {
    if error is NSError.Type {

其他回答

只是为了完整起见,基于公认的答案和其他一些答案:

let items : [Any] = ["Hello", "World", 1]

for obj in items where obj is String {
   // obj is a String. Do something with str
}

但是你也可以(compactMap也“映射”过滤器没有的值):

items.compactMap { $0 as? String }.forEach{ /* do something with $0 */ ) }

以及一个使用switch的版本:

for obj in items {
    switch (obj) {
        case is Int:
           // it's an integer
        case let stringObj as String:
           // you can do something with stringObj which is a String
        default:
           print("\(type(of: obj))") // get the type
    }
}

但回到问题上来,检查它是否是一个数组(即[String]):

let items : [Any] = ["Hello", "World", 1, ["Hello", "World", "of", "Arrays"]]

for obj in items {
  if let stringArray = obj as? [String] {
    print("\(stringArray)")
  }
}

或者更一般地说(见另一个问题的答案):

for obj in items {
  if obj is [Any] {
    print("is [Any]")
  }

  if obj is [AnyObject] {
    print("is [AnyObject]")
  }

  if obj is NSArray {
    print("is NSArray")
  }
}

如果你只想知道一个对象是否是给定类型的子类型,那么有一个更简单的方法:

class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}

func area (shape: Shape) -> Double {
  if shape is Circle { ... }
  else if shape is Rectangle { ... }
}

"使用类型检查操作符(is)来检查实例是否属于某个类型 子类的类型。如果实例为,则类型检查操作符返回true 如果不是,则为false "摘自:苹果公司《快速编程语言》。“iBooks。

在上面的句子中,“of a certain subclass type”很重要。is Circle和is Rectangle的使用被编译器接受,因为该值shape被声明为shape (Circle和Rectangle的超类)。

如果您使用的是基本类型,超类将是Any。这里有一个例子:

 21> func test (obj:Any) -> String {
 22.     if obj is Int { return "Int" }
 23.     else if obj is String { return "String" }
 24.     else { return "Any" }
 25. } 
 ...  
 30> test (1)
$R16: String = "Int"
 31> test ("abc")
$R17: String = "String"
 32> test (nil)
$R18: String = "Any"

myObject一样吗?如果myObject不是String, String返回nil。否则,它返回一个字符串?,所以你可以使用myObject访问字符串本身!,或者使用myObject强制转换它!作为字符串安全。

Swift 5.2 & Xcode版本:11.3.1(11C504)

以下是我检查数据类型的解决方案:

 if let typeCheck = myResult as? [String : Any] {
        print("It's Dictionary.")
    } else { 
        print("It's not Dictionary.") 
    }

我希望它能帮助你。

请注意:

var string = "Hello" as NSString
var obj1:AnyObject = string
var obj2:NSObject = string

print(obj1 is NSString)
print(obj2 is NSString)
print(obj1 is String)
print(obj2 is String) 

最后四行都返回true,这是因为如果你输入

var r1:CGRect = CGRect()
print(r1 is String)

... 它打印“假”当然,但警告说,Cast从CGRect到字符串失败。因此有些类型是桥接的,'is'关键字调用隐式强制转换。

你最好使用其中的一个:

myObject.isKind(of: MyClass.self)) 
myObject.isMember(of: MyClass.self))