Swift数组 - 使用类型为AnyObject的“Contains”

6

我想在类型为AnyObject的数组上使用contains函数。

import UIKit

var resultArray: Array<AnyObject> = Array()
resultArray.append(50)
resultArray.append(false)
resultArray.append("Test string")
let found = contains(resultArray, 50)

I get the error:

Type 'AnyObject -> L' does not conform to protocol 'IntegerLiteralConvertible'

enter image description here


不要在数组中混合类型,这不是一个好的做法。在这种情况下,将50作为字符串,以便所有项目都具有字符串类型。 - zaph
那么 AnyObject 的目的是什么? - Khawar
1
正如Zaph所说,除非你真的需要,否则使用AnyObject是不理想的。 AnyObject的一个用途是在编写或使用API时,获取一些数据类型未被程序员确定的信息。例如,Parse框架使用AnyObject,因为它不知道您是否存储了String、Bool、Int等。然后,你必须尽快将其转换。 - Byron Coetsee
@ByronCoetsee,是的,我正在编写一个API。这个数组是类变量,在协议委托方法中使用。实现此委托方法的类可能在完成块中返回任何类型的对象。这些对象的数组可能是某些字符串类型或某些模型类对象,例如“User”。 所有索引处的对象都是相同的,即字符串或用户。因此,最终该数组将转换为某种确定的类型。但是我不知道它们将是什么类型的对象。在类型未确定的情况下,我如何使用它? - Khawar
@Khawar 看看我的答案,看看能否帮到你。可能不是最有效的方法,但应该可以解决你的问题 :) - Byron Coetsee
5
你使用了 Comic Sans 字体。 - Steve Madsen
3个回答

9

我同意评论和其他答案; AnyObject 不是一个好的做法,但如果你 真的 想使用 AnyObject,你可以将你的 AnyObjects 数组视为一个 NSArray 对象,然后使用函数 containsObject()

if (resultArray as NSArray).containsObject(AnyObjectOfAnyType) {
     // Do something
}

@trevoj,谢谢,它可以工作。但我正在寻找更有效的解决方案。 - Khawar
@Khawar 更高效的方式是什么?你应该能够在这个if语句中检查任何可能的对象。 - trevorj
哈哈,你说得对。我一直在试图摆脱所有以“NS”开头的类型 :). 如果我找不到任何一个(我相信),我会接受你的答案。非常感谢你的解决方案。 - Khawar
太好了,很高兴听到这个消息!我将我的许多Array转换为NSArray,以使用仅NSArray具有的函数。 - trevorj
它的效率很低,因为它要求您坚持使用“AnyObject”,这意味着您放弃了Swift的所有值类型,并将所有内容转换为NSObjects(然后将整个数组从Array本身转换为NSArray)。虽然我知道您在回答开始时指出了这一点,即AnyObject是不良实践... :) - Airspeed Velocity
如果 AnyObject 不是好的编程实践,那么我还能用什么?我不知道数组会被填充什么类型的对象。 - Khawar

4
在这个例子中,你应该使用Any,因为你持有的是非class类型——否则将会进行到NSThing的隐式转换。
但是,这里有一种非ObjC-Interop的方法:
let found = contains(resultArray) { ($0 as? Int) == 50 }

@Airspeed,感谢您的回答。但它只检查“Int”。我只是举例检查了“50”。我需要一条语句,在运行时可以检查任何类型。 - Khawar
1
当我说:您在运行时可能实际上并不需要这种“动态”行为时,我真的不打算挑衅。我建议您发布一个带有您想要解决的实际问题背景的问题——很可能您可以使用编译时多态性(即通用算法)或运行时(即使用类/协议和动态调度)来解决它。从许多角度来看,使用AnyObject都很糟糕(使您陷入@objc领域,运行时效率低下,类型不安全等)。 - Airspeed Velocity

0

您可以使用is关键字来区分类型,然后使用上面Airspeed Velocity的代码片段来进行搜索...这是一个示例,如果需要,您可以修改并添加额外的类型:

if resultArray[0] is String {
    found = contains(resultArray) {
        ($0 as? String) == "hello"
    }
} else if resultArray[0] is Int {
    found = contains(resultArray) {
        ($0 as? Int) == 50
    }
}

注意:你说你的数组每次只包含一种类型 - 这很重要。


谢谢您的回答。但是我需要一个通用的检查,可以与Swift支持的任何类型一起使用。在您的示例中有多个检查。如果数组可以包含10种不同类型的对象,那么会有10个if语句吗? - Khawar
哦,我以为你说“所有索引处的对象都相同,即字符串或用户”时是指整个数组将是一个类型...不使用for循环对每个元素进行评估,我不知道。- for循环基本上可以使用我上面展示的代码,但只需评估每个元素;尽管这对于大型数组来说不是一个好主意。至于你关于10个if语句的问题,switch case更适合:P - Byron Coetsee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接