为什么 popFirst 抛出错误,但 removeFirst 有效?
Why popFirst throws an error, but removeFirst works?
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
错误是:
cannot use mutating member on immutable value: 'self' is
immutable
popFirst
and removeFirst
都标记为 mutating
,return 和 T?
。那为什么它不起作用?
编辑: 正如其他人评论的那样,这似乎是某种错误。它已在论坛 here.
中讨论过
编辑: 仍然发生在 Xcode 9.4.1 (Swift 4.1.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
(大写 S)是 self
(小写 s)的类型。这是您要调用的类型 popFirst
。在您的代码中,Self
是 Array<T>
,也拼写为 [T]
。
popFirst
这一行编译需要约束:
self = self[index(after: startIndex)..<endIndex]
^__^ ^_______________________________________^
| |
| This is a SubSequence.
|
This is a Self.
self[index(after: startIndex)..<endIndex]
是 SubSequence
.
Swift如果知道Self == SubSequence
.
只能将SubSequence
赋值给Self
Array
的 SubSequence
类型是 ArraySlice
。由于 ArraySlice
与 Array
不是同一类型,因此此扩展不适用于 Array
。
您可能正在寻找的扩展程序如下:
extension Array {
@inlinable
public mutating func popFirst() -> Element? {
if isEmpty {
return nil
} else {
return removeFirst()
}
}
}
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
错误是:
cannot use mutating member on immutable value: 'self' is immutable
popFirst
and removeFirst
都标记为 mutating
,return 和 T?
。那为什么它不起作用?
编辑: 正如其他人评论的那样,这似乎是某种错误。它已在论坛 here.
中讨论过编辑: 仍然发生在 Xcode 9.4.1 (Swift 4.1.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
(大写 S)是 self
(小写 s)的类型。这是您要调用的类型 popFirst
。在您的代码中,Self
是 Array<T>
,也拼写为 [T]
。
popFirst
这一行编译需要约束:
self = self[index(after: startIndex)..<endIndex] ^__^ ^_______________________________________^ | | | This is a SubSequence. | This is a Self.
self[index(after: startIndex)..<endIndex]
是 SubSequence
.
Swift如果知道Self == SubSequence
.
SubSequence
赋值给Self
Array
的 SubSequence
类型是 ArraySlice
。由于 ArraySlice
与 Array
不是同一类型,因此此扩展不适用于 Array
。
您可能正在寻找的扩展程序如下:
extension Array {
@inlinable
public mutating func popFirst() -> Element? {
if isEmpty {
return nil
} else {
return removeFirst()
}
}
}