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()
    }
}
The error I get for popFirst is:
cannot use mutating member on immutable value: 'self' is immutable
Both popFirst and removeFirst are marked as mutating and both return and T?. So why isn't it working?
EDIT: As others have commented, it seems to be some sort of bug. It's been discussed in the forums here.
EDIT: Still happens in Xcode 9.4.1 (Swift 4.1.2)
The error is improved in 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!
                        ^
You get the error because popFirst is not defined for all Collections. It's only defined if the Collection is its own SubSequence type. 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
  }
}
The extension requires SubSequence == Self. Self (with a capital S) is the type of self (with a lower-case s). It is the type on which you're calling popFirst. In your code, Self is Array<T>, also spelled [T].
The constraint is necessary for this line of popFirst to compile:
self = self[index(after: startIndex)..<endIndex] ^__^ ^_______________________________________^ | | | This is a SubSequence. | This is a Self.
self[index(after: startIndex)..<endIndex] is a SubSequence.
Swift can only assign a SubSequence to Self if it knows that Self == SubSequence.
Array's SubSequence type is ArraySlice. Since ArraySlice is not the same type as Array, this extension doesn't apply to Array.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With