func getIndex<T: Equatable>(valueToFind: T) -> Int? {...}

mutating func replaceObjectWithObject<T: Equatable>(obj1: T, obj2: T) {
    if let index = self.getIndex(obj1) {
        self.removeAtIndex(index)
        self.insert(obj2, atIndex: index)           // Error here: 'T' is not convertible to 'T'
    }
}

我有那个功能,想用另一个元素替换一个元素。但是我对Generics不太熟悉,也不知道为什么这不起作用。请帮忙。

如果我从变异函数中删除了Equatable,则错误消息会跳到该函数的第一行,然后如果我将其替换为func find(),它会给我与第3行相同的错误。

最佳答案

在Swift的现有协议(protocol)和泛型系统下,通过扩展实际上是不可能的-您无法向类型的泛型子类型添加其他约束,因此无法使用要求其内容一致的方法来扩展ArrayEquatable

您可以通过内置的Array类型看到此限制的作用-没有myArray.find(element)方法,但是有一个全局函数find()接受一个集合和一个元素,并且具有一个通用约束,即集合的元素是Equatable:

func find<C : CollectionType where C.Generator.Element : Equatable>(domain: C, value: C.Generator.Element) -> C.Index?

可以为您的方法执行此操作-您只需要编写一个类似的顶层函数即可:
func replaceObjectWithObject<C : RangeReplaceableCollectionType where C.Generator.Element : Equatable>(inout collection: C, obj1: C.Generator.Element, obj2: C.Generator.Element) {
    if let index = find(collection, obj1) {
        removeAtIndex(&collection, index)
        insert(&collection, obj2, atIndex: index)
    }
}

var myArray = [1, 2, 3, 4, 5]
replaceObjectWithObject(&myArray, 2, 7)
// 1, 2, 7, 4, 5

10-08 13:32