我想在Swift中使用更多函数式编程。我编写的一些函数可以在各种类型的数组上很好地工作。我不想用不同的类型(或typealases)重写相同的函数。函数的工作方式通常是相同的,只是使用不同的类型。所以,我试过这样的事情:
// Add indeces to an array of any type. I.e., returns an array of tuples of the array index and the original element.
func addIndeces<T: AnyObject>(toArray: Array<T>) -> Array<(index: Int, value: T)> {
var arrIndex: [Int] = []
for index in 0...toArray.count {
arrIndex.append(index)
}
return Array(Zip2(arrIndex, toArray))
}
当我调用此函数时
// Note: reminderList is of type [Reminder]
let indexedReminderList = addIndeces(reminderList) as! [(index: Int, reminder: Reminder)]
我收到运行时错误:“致命错误:不能在不同大小的类型之间使用unsafeBitCast”
我做错了什么?
答案 0 :(得分:2)
你正在写的功能已经存在 - 有点像。 enumerate
“返回包含对{la> n , x )的惰性SequenceType
,其中 n \ s是连续的{ {1}} \ s从零开始, x \ s是Int
“
这意味着您可以将您的功能编写为:
base
注意,您不需要编写func addIndices<T>(toArray: [T]) -> [(index: Int, reminder: T)] {
// if you want to label the tuple elements index: and reminder:,
// you still have to use map:
return map(enumerate(toArray)) {
(index: $0, reminder: $1)
}
}
,除非具体想要阻止此函数接受除类数组之外的任何内容(因为T: AnyObject
是AnyObject
- 只有类,而不是结构或枚举符合的协议。)
注意,enumerate
仅适用于整数索引集合。为了使其更通用,您可以编写zip(indices(someCollection),someCollection))
。 indices
返回任何集合的所有索引的范围,因此等同于someCollection.startIndex..<someCollection.endIndex
。
答案 1 :(得分:1)
您希望将Array
类型为[(index: Int, value: T)]
的元组T
转换为类型为Reminder
的元组Array
[(index: Int, reminder: Reminder)]
。所以你可以看到元组有不同的元素名称(值和提醒),两者都有不同的字节大小 - 因此错误。
因此,您应该为两个元组使用相同的元素名称。
如果要更改元素名称:
let newTupleArray = oldTupleArray.map{ (newElementName0: $0.0, newElementName1: $0.1) }
答案 2 :(得分:0)
范围0...toArray.count
包含从0到toArray计数的所有元素,包括计数值,在您的情况下,arrIndex
将始终有一个元素,然后是toArray。这是造成不同尺寸错误的原因。要解决此问题,请使用此0..<toArray.count