【问题标题】:Swift generics and extensions need to workout [duplicate]Swift泛型和扩展需要锻炼[重复]
【发布时间】:2015-06-25 12:02:16
【问题描述】:

我目前正在快速学习。在学习时,我被泛型所困扰。我正在解决一个简单的问题,即 -> 返回数组中指定元素的索引

import UIKit

extension Array
{

func indexOfLetter<T:Equatable>(item:T) -> Int
{
    var i = 0
    for (index, value) in enumerate(self)
    {
        if value == item
        {
            return i
        }
        i++
    }

    return -1;
}
}


var arrayOfItems = ["A","B"]
arrayOfItems.indexOfLetter("A")

在这段代码中,我遇到了我们的错误

无法使用 == 运算符比较 T 类型的两个操作数。

【问题讨论】:

  • 它没有描述您的问题,但您可以消除 var i 和当前不必要地未使用的 return index...并且该方法会更好地返回Int? 并在未找到时传回 nil 而不是 -1
  • 这与引用问题中的问题相同:您不能在对模板更严格的泛型类型上编写方法。 – 在 Swift 1.2 中,您将不得不定义一个全局函数。在 Swift 2 中,您可以通过协议扩展来解决它。
  • 我通过打开对象找到了解决方案。导入 UIKit 扩展数组 { func indexOfLetter(item:U) -> Int { var i = 0 for (index, value) in enumerate(self) { if (value as!NSString) == (item as! NSString) { return i } i++ } return -1; } } var arrayOfItems:Array = ["A","B"] arrayOfItems.indexOfLetter("B")

标签: swift generics protocols


【解决方案1】:

如果我们使用T 以外的字母作为我们的通用标识符,您的问题的答案就会变得更加清晰。

更改方法签名以使用字母U。现在我们得到这个错误信息:

二元运算符“==”不能应用于“T”和“U”类型的操作数

这是同一个错误,但使用不同的字母更清楚。 Array 类型已经是一个泛型,其类型的泛型标识符是T

当我们使用U 时,它揭示了真正的问题。

Equatable 协议只要求我们的类型定义 == 以便与自身进行比较。只要U 的类型是Equatable,我们就可以比较两个U。但是Equatable 协议并不能确保我们可以使用==UT 进行比较。

This Stack Overflow answer 可以提供一些关于将Equatable 协议与泛型一起使用的困难的一些见解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多