Reputation: 1775
I am following along in the Stanford iOS course and I have a question that I believe is related to a recent update. Here is the section of code:
func evaluate(ops: [Op]) -> (result: Double?,remainingOps: [Op]) {
let op = ops.removeLast() //*I thought ops was immutable?
}
On the video, the instructor gets an error that says you cannot do this because ops is immutable. This makes complete sense but when I try typing this in I do not get an error. What does this mean? Is this a change in a recent Swift update that structs passed into methods are mutable? Any ideas? In the video, the instructor solves the problem by creating an instance variable which is a copy of ops but I no longer get the error and would like to understand why this is.
EDIT When typing this into a playground I still get the error but I do not in my Swift File. For reference here is the entire file so far. Any ideas? I just want to understand what is going on here:
import Foundation
class CalculatorBrain {
private enum Op {
case Operand(Double)
case UnaryOperation(String,Double -> Double)
case BinaryOperation(String, (Double,Double) -> Double)
}
private var opStack = [Op]()
private var knownOps = [String:Op]()
init() {
knownOps["×"] = Op.BinaryOperation("×",*)
knownOps["÷"] = Op.BinaryOperation("÷") { $1 / $0 }
knownOps["+"] = Op.BinaryOperation("+",+)
knownOps["−"] = Op.BinaryOperation("−") { $1 - $0 }
knownOps["^"] = Op.BinaryOperation("^") { pow($1,$0) }
knownOps["√"] = Op.UnaryOperation("√",sqrt)
knownOps["sin"] = Op.UnaryOperation("sin") { sin($0) }
knownOps["cos"] = Op.UnaryOperation("cos") { cos($0) }
knownOps["tan"] = Op.UnaryOperation("tan") { tan($0) }
}
func evaluate(ops: [Op]) -> (result: Double?,remainingOps: [Op]) {
if !ops.isEmpty {
let op = ops.removeLast()//*Error should appear here but does not
}
return (nil,ops)
}
func evaluate() -> Double? {
}
func pushOperand(operand: Double) {
opStack.append(Op.Operand(operand))
}
func performOperation(symbol: String) {
if let operation = knownOps[symbol] {
opStack.append(operation)
}
}
}
Upvotes: 0
Views: 177
Reputation: 510
I've just tried this now with the following Playground code which throws up an error (Xcode 6.3.1):
//: Playground - noun: a place where people can play
import UIKit
import XCPlayground
//: Developing iOS 8 Apps with Swift 3. Applying MVC 40 minutes in
enum Op {
case Operand(Double)
case UnaryOperation(String, Double -> Double)
case BinaryOperation(String, (Double, Double) -> Double)
}
var knownOps = [String:Op]()
knownOps["x"] = Op.BinaryOperation("x", *)
// by putting let for the parameter we are declaring ops as immutable
// the default is for each parameter is let
func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op]) {
if !ops.isEmpty {
let op = ops.removeLast() // Immutable value of type '[Op]' only has mutating members named 'removeLast'
}
return (nil, ops)
}
if I change evaluate(ops: [Op])
to evaluate(var ops: [Op])
, the same as in the video it removes the error. I'm thinking that there is something wrong with the Xcode project you are using - maybe try restarting Xcode (the old off 'n on)?
Upvotes: 0
Reputation: 326
I have just checked to see if it implicitly makes copy of array. No it does not. Your xCode is in bug i think. Please restart xCode and try again. Go to utilities bar, move your cursor on ops array in the code. What do you observe as a type? "error type"
or something else? You can also check this by pressing opt
and click to the variable.
Upvotes: 1