【问题标题】:Swift Generics issueSwift 泛型问题
【发布时间】:2014-06-04 09:46:46
【问题描述】:

现在我希望能够查看一个对象是否包含在 Array 中,所以:

func isIncluded<U:Comparable>(isIncluded : U) -> Bool
{
    for item in self
    {
        if (item == isIncluded)
        {
            return true
        }
    }

    return false
}

如果你注意到这个函数属于Array 扩展。问题是如果将其添加到此:

extension Array{

}

我收到以下错误:

找不到接受所提供参数的“==”的重载

我知道我可能需要告诉Array 中应该包含哪些类型的对象,如下所示:T[] &lt;T.GeneratorType.Element: Comparable&gt;。但它也不起作用:

大括号语句块是未使用的闭包
非标称类型“T[]”不能扩展
扩展中应为“{”

【问题讨论】:

    标签: swift


    【解决方案1】:

    对于 Swift,我们需要考虑是否有一个 函数 可以做到这一点——在类的方法之外。

    就像我们这里的例子:

    contains(theArray, theItem)
    

    你可以在操场上试试:

    let a = [1, 2, 3, 4, 5]
    contains(a, 3)
    contains(a, 6)
    

    我通过 cmd 单击 Swift 符号(例如:Array)然后在该文件中四处查看(这似乎是包含所有声明的全局文件Swift 通用类和函数)。

    这里有一个小扩展,它将“包含”方法添加到所有数组:

    extension Array {
        func contains<T: Equatable>(item: T) -> Bool {
            for i in self {
                if item == (i as T) { return true }
            }
            return false
        }
    }
    

    【讨论】:

    • 我一直在这样做,我知道它存在,我宁愿选择theArray.contains(element) 而不是contains(theArray,element)
    • @JackyBoy 我创建了一个小扩展来满足你的愿望:)
    • 请注意,您需要使用可选的类型转换:if item == (i as? T),这样您就不会在类型与数组的项目类型不匹配时崩溃。此外,此方法不适用于可选对象数组(即String?[]
    • @JohnEstropia John,关于可选选项你绝对是对的......我还没有找到一个通用的解决方案......
    • @JeanLeMoignan 查看我的答案以获得一般解决方案。
    【解决方案2】:

    补充一下,问题是T已经定义了,而Array对T的定义不符合Equatable。您可以通过强制转换(像接受的答案)来完成您想要的事情,并冒着无效转换的风险,或者您可以传入不需要强制转换的委托。

    考虑这样修改:

    extension Array {
       func contains(comparator: (T)->Bool) -> Bool {
        for item in self {
            if comparator(item) {
               return true
            }
        }
        return false
      }
    }
    

    示例用法:

    class Test {
        func arrayContains(){
            var test: Int[] = [0,1,3,4,5]
            //should be true 
            var exists = test.contains({(item)->Bool in item == 0});
        }
    }
    

    【讨论】:

    • 很好的方法,因为“Any”没有实现 Equatable。一个不太冗长的例子是 "assert(["one", "two"].contains({$0 == "one"}))"
    【解决方案3】:

    并不是说这是不可能的,但我还没有看到一种方法来扩展结构或类以对原始泛型设置条件,例如保证数组上的EquatableComparable。但是,对于您的特定问题,您可以执行以下操作,而不是扩展:

    var arr = [1, 2, 3]
    var isIncluded : Bool = arr.bridgeToObjectiveC().doesContain(1) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-06
      • 2018-07-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多