检查对象是否是Swift中的给定类型

问题描述 投票:228回答:16

我有一个由AnyObject组成的数组。我想迭代它,并找到所有元素作为数组实例。

如何在Swift中检查对象是否属于给定类型?

swift type-inference typechecking
16个回答
268
投票

如果要检查特定类型,可以执行以下操作:

if let stringArray = obj as? [String] {
    // obj is a string array. Do something with stringArray
}
else {
    // obj is not a string array
}

你可以使用“as!”如果obj不是[String]类型,那将抛出运行时错误

let stringArray = obj as! [String]

您还可以一次检查一个元素:

let items : [Any] = ["Hello", "World"]
for obj in items {
   if let str = obj as? String {
      // obj is a String. Do something with str
   }
   else {
      // obj is not a String
   }
}

2
投票

为什么不使用这样的东西

fileprivate enum types {
    case typeString
    case typeInt
    case typeDouble
    case typeUnknown
}

fileprivate func typeOfAny(variable: Any) -> types {
    if variable is String {return types.typeString}
    if variable is Int {return types.typeInt}
    if variable is Double {return types.typeDouble}
    return types.typeUnknown
}

在Swift 3中。


1
投票

如果myObject as? String不是nilmyObject会返回String。否则,它返回一个String?,因此您可以使用myObject!访问字符串本身,或者安全地使用myObject! as String进行转换。


1
投票

斯威夫特3:

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

if aShape.isKind(of: Circle.self) {
}

0
投票

如果您有这样的响应:

{
  "registeration_method": "email",
  "is_stucked": true,
  "individual": {
    "id": 24099,
    "first_name": "ahmad",
    "last_name": "zozoz",
    "email": null,
    "mobile_number": null,
    "confirmed": false,
    "avatar": "http://abc-abc-xyz.amazonaws.com/images/placeholder-profile.png",
    "doctor_request_status": 0
  },
  "max_number_of_confirmation_trials": 4,
  "max_number_of_invalid_confirmation_trials": 12
}

并且你想检查将被读作AnyObject的值is_stucked,你所要做的就是这个

if let isStucked = response["is_stucked"] as? Bool{
  if isStucked{
      print("is Stucked")
  }
  else{
      print("Not Stucked")
 }
}

0
投票

如果您不知道在服务器的响应中将获得一个字典数组或单个字典,则需要检查结果是否包含数组。 在我的情况下,除了一次之外总是收到一系列字典。所以,为了处理我使用下面的swift 3代码。

if let str = strDict["item"] as? Array<Any>

在这里? Array检查获取的值是否为数组(字典项)。在其他情况下,如果它是单个字典项而不保留在数组中,则可以处理。


0
投票

Swift 4.2,在我的例子中,使用isKind函数。

isKind(of :)返回一个布尔值,指示接收者是给定类的实例还是从该类继承的任何类的实例。

  let items : [AnyObject] = ["A", "B" , ... ]
  for obj in items {
    if(obj.isKind(of: NSString.self)){
      print("String")
    }
  }

Readmore https://developer.apple.com/documentation/objectivec/nsobjectprotocol/1418511-iskind


0
投票

只是为了基于已接受的答案和其他一些完整性:

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

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

但你也可以(compactMap也“映射”filter没有的值):

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)")
  }
}

或者更普遍(见this other question answer):

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")
  }
}

170
投票

Swift 2.2 - 5你现在可以做:

if object is String
{
}

然后过滤你的数组:

let filteredArray = originalArray.filter({ $0 is Array })

如果您要检查多种类型:

    switch object
    {
    case is String:
        ...

    case is OtherClass:
        ...

    default:
        ...
    }

149
投票

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

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

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

“使用类型检查运算符(是)检查实例是否属于某个子类类型。如果实例属于该子类类型,则类型检查运算符返回true,否则返回false。“摘录自:Apple Inc.”Swift编程语言。“iBooks

在上文中,“某个子类型”的短语很重要。 is Circleis Rectangle的使用被编译器接受,因为该值shape被声明为ShapeCircleRectangle的超类)。

如果您使用的是原始类型,那么超类将是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"

20
投票

我有两种方法:

if let thisShape = aShape as? Square 

要么:

aShape.isKindOfClass(Square)

这是一个详细的例子:

class Shape { }
class Square: Shape { } 
class Circle: Shape { }

var aShape = Shape()
aShape = Square()

if let thisShape = aShape as? Square {
    println("Its a square")
} else {
    println("Its not a square")
}

if aShape.isKindOfClass(Square) {
    println("Its a square")
} else {
    println("Its not a square")
}

编辑:3现在:

let myShape = Shape()
if myShape is Shape {
    print("yes it is")
}

14
投票

对于swift4:

if obj is MyClass{
    // then object type is MyClass Type
}

9
投票

假设drawTriangle是UIView的一个实例。要检查drawTriangle是否为UITableView类型:

在Swift 3中,

if drawTriangle is UITableView{
    // in deed drawTriangle is UIView
    // do something here...
} else{
    // do something here...
}

这也可以用于您自己定义的类。您可以使用它来检查视图的子视图。


4
投票

为什么不使用专门为此任务构建的内置功能?

let myArray: [Any] = ["easy", "as", "that"]
let type = type(of: myArray)

Result: "Array<Any>"

4
投票

请注意这个:

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)

...当然打印“假”,但是警告说从CGRect转换为String失败。因此某些类型被桥接,而'is'关键字调用隐式强制转换。

你应该更好地使用其中一个:

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

2
投票

如果你只是想检查类而没有得到警告,因为未使用的定义值(让someVariable ......),你可以简单地用布尔值替换let东西:

if (yourObject as? ClassToCompareWith) != nil {
   // do what you have to do
}
else {
   // do something else
}

当我使用let方式并且没有使用定义的值时,Xcode提出了这个。

© www.soinside.com 2019 - 2024. All rights reserved.