Search code examples
swiftvarletfor-in-loop

Initializing variables in Swift without var/let


I'm new to Swift so this might come as a noob question but I will be thankful if someone cleared the doubt because I cannot find any explanation online. While using for-in loop, sometimes the variables have not been initialized before and still there is no compiler error. Sometimes if I try to write var/let before them, it shows error- 'let' pattern cannot appear nested in an already immutable context

e.g., in the code below, why have the variables movie and releasedDate not been initialized before?

class MovieArchive {
func filterByYear(year:Int, movies:Dictionary<String, Int> ) -> [String]{
    var filteredArray = [String]()
    for (movie, releaseDate) in movies {
        if year == releaseDate {
            filteredArray.append(movie)
        }
    }
    return filteredArray
}

}

var aiThemedMovies = ["Metropolis": 1927, "2001: A Space Odyssey": 1968, "Blade Runner": 1982, "War Games": 1983, "Terminator": 1984, "The Matrix": 1999, "A.I.": 2001, "Her": 2013, "Ex Machina": 2015]

var myArchive = MovieArchive()
myArchive.filterByYear(year: 2013
, movies: aiThemedMovies)

Thanks in advance for any help :)


Solution

  • Swift does initialise movie and releaseDate using let, but simplifies that initialisation so that you can just assume that they're set to the correct variables from movies every time the loop iterates. That's why you don't need to write let before movie and releaseDate.

    If you write var in front of the variable, you can mutate the value in the array that it points to. If it's a let, then it won't let you mutate it.

    For example, if you place var in front of one of the variables, this code will change all the releaseDates to 2000:

    class MovieArchive {
        func filterByYear(year:Int, movies:Dictionary<String, Int> ) -> [String]{
            var filteredArray = [String]()
            for (movie, var releaseDate) in movies {
                releaseDate = 2000
                if year == releaseDate {
                    filteredArray.append(movie)
                }
            }
            return filteredArray
        }
    }