struct Queue<T>{
private var elements : [T] = []
public mutating func enqueue(_ element: T){
elements.append(element)
}
public mutating func dequeue() -> T?{
return elements.popFirst() // ERROR!
}
public mutating func dequeue2() -> T?{
return elements.removeFirst()
}
}
我为popFirst
收到的错误是:
不能在不可变值上使用变异成员:&#39; self&#39;是 不可变
popFirst
和removeFirst
都标记为mutating
,并且都返回T?
。那么为什么它不起作用呢?
编辑:正如其他人评论的那样,它似乎是某种错误。它已在论坛here中进行了讨论。
编辑:仍然在Xcode 9.4.1(Swift 4.1.2)中发生
答案 0 :(得分:2)
该错误在Swift 4.2中得到了改善:
error: ios.playground:4:25: error: '[T]' requires the types '[T]' and 'ArraySlice<T>' be equivalent to use 'popFirst'
return elements.popFirst() // ERROR!
^
由于未为所有popFirst
定义Collection
,所以收到错误消息。仅当Collection
是其自己的SubSequence
类型时才定义。 Here's the implementation:
extension Collection where SubSequence == Self {
/// Removes and returns the first element of the collection.
///
/// - Returns: The first element of the collection if the collection is
/// not empty; otherwise, `nil`.
///
/// - Complexity: O(1)
@inlinable
public mutating func popFirst() -> Element? {
// TODO: swift-3-indexing-model - review the following
guard !isEmpty else { return nil }
let element = first!
self = self[index(after: startIndex)..<endIndex]
return element
}
}
我认为扩展名需要SubSequence == Self
,因为self[index(after: startIndex)..<endIndex]
返回了SubSequence
,除非self
(符合{ {1}}和它的Self
是同一类型。
Collection
的{{1}}类型是SubSequence
,而不是Array
,因此此扩展名不适用于SubSequence
。
答案 1 :(得分:1)
以下是您可能正在寻找的扩展名:
extension Array {
@inlinable
public mutating func popFirst() -> Element? {
if isEmpty {
return nil
} else {
return removeFirst()
}
}
}