【发布时间】:2015-02-27 14:34:25
【问题描述】:
我目前正在尝试在 Swift 中实现我自己的 DynamicArray 数据类型。为此,我使用了一些指针。作为我的root,我使用的是泛型类型的UnsafeMutablePointer T:
struct DynamicArray<T> {
private var root: UnsafeMutablePointer<T> = nil
private var capacity = 0 {
didSet {
//...
}
}
//...
init(capacity: Int) {
root = UnsafeMutablePointer<T>.alloc(capacity)
self.capacity = capacity
}
init(count: Int, repeatedValue: T) {
self.init(capacity: count)
for index in 0..<count {
(root + index).memory = repeatedValue
}
self.count = count
}
//...
}
现在你可以看到我还实现了一个capacity 属性,它告诉我当前为root 分配了多少内存。因此,可以使用init(capacity:) 初始化程序创建DynamicArray 的实例,该初始化程序分配适当的内存量,并设置capacity 属性。
但后来我还实现了init(count:repeatedValue:) 初始化程序,它首先使用init(capacity: count) 分配所需的内存。然后它将该部分内存中的每个段设置为repeatedValue。
将init(count:repeatedValue:) 初始化器与Int、Double 或Float 等数字类型一起使用时,它可以正常工作。然后使用Character 或String,尽管它会崩溃。虽然它不会一直崩溃,但实际上有时会起作用,正如 here 所见,通过编译几次。
var a = DynamicArray<Character>(count: 5, repeatedValue: "A")
println(a.description) //prints [A, A, A, A, A]
//crashes most of the time
var b = DynamicArray<Int>(count: 5, repeatedValue: 1)
println(a.description) //prints [1, 1, 1, 1, 1]
//works consistently
为什么会这样?是否与 String 和 Character 持有不同长度的值有关?
更新 #1:
现在@AirspeedVelocity 解决了init(count:repeatedValue:) 的问题。 DynamicArray 包含另一个初始化器,它最初的工作方式与 init(count:repeatedValue:) 类似。正如@AirspeedVelocity 为init(count:repeatedValue:) 所描述的那样,我将其更改为工作:
init<C: CollectionType where C.Generator.Element == T, C.Index.Distance == Int>(collection: C) {
let collectionCount = countElements(collection)
self.init(capacity: collectionCount)
root.initializeFrom(collection)
count = collectionCount
}
我正在使用initializeFrom(source:) 方法,如here 所述。并且由于 collection 符合 CollectionType 它应该可以正常工作。
我现在收到此错误:
<stdin>:144:29: error: missing argument for parameter 'count' in call
root.initializeFrom(collection)
^
这又是一个误导性的错误信息吗?
【问题讨论】:
-
我认为这是一个@MartinR 问题
-
您不应该通过编辑之前的问题来提出新的不同问题……但是,我相信您在 1.1 中遇到了快速类型推断错误,该错误已在 1.2 测试版中修复。
-
好的,以后我会尽量避免这种情况。 - 该死的
标签: string swift pointers generics unsafe-pointers