我有一个由AnyObject
组成的数组。我想遍历它,并找到所有是数组实例的元素。
如何在Swift中检查对象是否为特定类型?
我有一个由AnyObject
组成的数组。我想遍历它,并找到所有是数组实例的元素。
如何在Swift中检查对象是否为特定类型?
如果您想针对特定类型进行检查,可以按照以下方式操作:
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
}
}
?
,为什么只会抛出运行时错误而不是编译时错误呢?听起来像是as
和?
组合在一起会执行运行时检查。什么情况下适合使用没有?
的as
呢?提前致谢。 - Unheiligas
而不带上 ?
,因为如果不是该类型,程序将立即停止。在 if
语句中使用 ?
可以让程序继续执行。 - drewag=
) 不再像在 C 中那样返回一个值。这是为了防止在 if 语句中意外使用 =
而不是 ==
导致的错误。 - drewagif
语句中使用 var
和 let
应该没有任何区别,对吗?我知道它们的区别,只是想问当它们在 if
语句中时是否有区别。 - Unheilig在Swift 2.2 - 5中,您现在可以执行以下操作:
if object is String
{
}
然后对您的数组进行过滤:
let filteredArray = originalArray.filter({ $0 is Array })
如果您需要检查多种类型:
switch object
{
case is String:
...
case is OtherClass:
...
default:
...
}
object
当作 String
使用(至少在 Swift 2 中是这样),然而通过使用 let
解决方案则可以。 - Ferran Maylinchobject
是可以的。 - meaning-mattersobject.uppercaseString
,因为变量的类型没有转换为该类型,你只是检查了对象(由变量指向)是否为 String
。 - Ferran Maylinch如果你只想知道一个对象是否是给定类型的子类型,那么有一种更简单的方法:
class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}
func area (shape: Shape) -> Double {
if shape is Circle { ... }
else if shape is Rectangle { ... }
}
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"
is
还能正常工作吗?谢谢。 - UnheiligAnyObject
,似乎因为AnyObject
没有继承自NSObject
而被反驳了。如果Any
不同,那么这也将是一个很好的解决方案。谢谢。 - Unheilig针对Swift 4:
if obj is MyClass{
// then object type is MyClass Type
}
我有两种做法:
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")
}
isKindOfClass
是NSObject
协议的一个方法;它只适用于采用该协议的类(所有下降自NSObject的类,以及任何明确采用它的自定义Swift类)。 - Nicolas Miari假设drawTriangle
是一个UIView
的实例。为了检查drawTriangle
是否属于UITableView
类型:
在Swift 3中,
if drawTriangle is UITableView{
// in deed drawTriangle is UIView
// do something here...
} else{
// do something here...
}
这也可以用于您自己定义的类。您可以使用它来检查视图的子视图。
为了完整起见,基于已接受的答案和一些其他内容:
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)")
}
}
更普遍地说(请参见这个问题的另一个回答):
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")
}
}
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 {
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)
当然,它会打印出“false”,但是一个警告表明从CGRect到String的转换失败。因此,某些类型被桥接,并且“is”关键字调用了一个隐式转换。
你最好使用以下之一:
myObject.isKind(of: MyClass.self))
myObject.isMember(of: MyClass.self))
为什么不使用专门为此任务而构建的内置功能呢?
let myArray: [Any] = ["easy", "as", "that"]
let type = type(of: myArray)
Result: "Array<Any>"