0

I just started to learn Swift 3. I am a little bit experienced in C++ but I am a bit confused when it comes to constants in Swift.

Following code:

class Auto {

    var maxKmH:Int = 50;
    var color:String = "green";
}


class Autohaus
{
    public var Autos:[Auto] = [];
    let amount:Int;

    func addAutos()
    {
        for i in 0..<self.amount{
            var car = Auto(); // warning to replace VAR with LET ???
            Autos.append(car);
        }
    }
}

So Xcode advises me to use let instead of var in the following line

var car = Auto(); 

When I do that, the warning disappears HOWEVER I can still change the object (for example the attributes).

This confuses me a bit, since a constant actually can be changed? Why do I need let then, if it's mutable?

Thanks guys!

Hamish
  • 78,605
  • 19
  • 187
  • 280
André
  • 351
  • 1
  • 5
  • 19
  • 1
    If you changed `Auto` from being a `class` to a `struct`, you'd get the desired behaviour of immutability with `let`. – Hamish Feb 06 '17 at 17:33
  • Also note that you don't need semicolons at the end of statements, property and variable names should be `lowerCamelCase`, and you don't have to give explicit type annotations on declarations where the compiler can infer the type (e.g `var color = "green"`). – Hamish Feb 06 '17 at 17:35
  • Thank you very much @Hamish for linking the other thread. I was reading it and I get it now! The only thing I am wondering, is what is in my case the benefit of using let instead of var, since I can (and want) to edit my attributes anyway? Is there in general a benefit of using let instead of var for objects of classes? The only benefit I see, is telling my Array of class Autohaus, that I don't want to change the objects (reference). – André Feb 06 '17 at 17:51
  • and thanks for the other advices :) – André Feb 06 '17 at 17:52
  • 1
    Using `let` lets you communicate that you don't intend for a given value to change – as you say, this is still applicable for reference types, as you won't be able to change the reference to a class instance if you annotate it as a `let`. Besides this, it also allows the compiler to perform various optimisations with the knowledge that a given value cannot change. – Hamish Feb 06 '17 at 18:04
  • Thank you very much @Hamish, that make sense! I have one last question: Is there a better way to do this: var car = Auto(); Autos.append(car); Because it seems like I waste memory for creating a variable and then put it in an array anyway. Wouldn't it be better if I could do something like: Autos.append(Auto()); Because it seems that I don't waste extra memory for a var which will be copied anyway into the array. – André Feb 06 '17 at 18:06
  • oh and I would like to mark it as good answers, but unfortunately I can't do it with a comment :) – André Feb 06 '17 at 18:08
  • 1
    No problem :) I don't believe it will make a difference (memory wise) doing `let car = Auto(); autos.append(car)` vs. `autos.append(Auto())`. I believe both will allocate stack space for the reference caller-side, although I could be wrong. In any case, the only extra cost would be a reference on the stack, which is trivial. Simply choose the option that you find the most readable. – Hamish Feb 06 '17 at 18:25

0 Answers0