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

时间:2014-06-06 23:04:37

标签: swift type-inference typechecking

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

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

18 个答案:

答案 0 :(得分:259)

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

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

答案 1 :(得分:160)

现在可以在Swift 2.2 - 5中执行:

if object is String
{
}

然后过滤你的数组:

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

如果您要检查多种类型:

    switch object
    {
    case is String:
        ...

    case is OtherClass:
        ...

    default:
        ...
    }

答案 2 :(得分:148)

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

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"

答案 3 :(得分:19)

我有两种方法:

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

答案 4 :(得分:14)

for swift4:

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

答案 5 :(得分:9)

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

Swift 3 中,

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

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

答案 6 :(得分:4)

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

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

Result: "Array<Any>"

答案 7 :(得分: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))

答案 8 :(得分: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中。

答案 9 :(得分:2)

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

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

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

答案 10 :(得分:1)

斯威夫特3:

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

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

答案 11 :(得分:1)

如果myObject as? String不是nil,则

myObject会返回String。否则,它会返回String?,因此您可以使用myObject!访问字符串本身,或者安全地使用myObject! as String投放该字符串。

答案 12 :(得分:1)

as?不会总是给您预期的结果,因为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 {

答案 13 :(得分: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")
 }
}

答案 14 :(得分:0)

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

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

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

答案 15 :(得分:0)

Swift 4.2,就我而言,使用isKind函数。

  

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

i=1

阅读更多https://developer.apple.com/documentation/objectivec/nsobjectprotocol/1418511-iskind

答案 16 :(得分: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")
  }
}

答案 17 :(得分:0)

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

我希望它能对您有所帮助。