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)和泛型系统下,通过扩展实际上是不可能的-您无法向类型的泛型子类型添加其他约束,因此无法使用要求其内容一致的方法来扩展Array
到Equatable
。
您可以通过内置的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