在没有var / let的情况下在Swift中初始化变量

时间:2016-12-07 13:26:46

标签: swift var let for-in-loop

我是Swift的新手,所以这可能是一个noob问题,但如果有人清除了疑问,我会感激,因为我无法在网上找到任何解释。在使用for-in循环时,有时变量尚未在之前初始化,并且仍然没有编译器错误。有时如果我尝试在它们之前编写var / let,它会显示错误 - 'let'模式不能嵌套在已经不可变的上下文中

例如,在下面的代码中,为什么变量movie和releasedDate之前没有被初始化?

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)

提前感谢您的任何帮助:)

3 个答案:

答案 0 :(得分:1)

Swift会使用movie初始化releaseDatelet,但会简化初始化,以便您可以假设它们已从movies设置为正确的变量循环迭代的时间。这就是为什么你不需要在moviereleaseDate之前写一下。

如果在变量前面写var,则可以改变它指向的数组中的值。如果它是一个let,那么它不会让你改变它。

例如,如果将var放在其中一个变量的前面,则此代码会将所有releaseDates更改为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
    }
}

答案 1 :(得分:1)

在不考虑实际用法的情况下,让我们来谈谈for循环中语法合法的内容。这是合法的:

    for var i in 1...3 { // ok
        print(i)
        i = 0
    }

这不合法:

    for let i in 1...3 { // error
        print(i)
    }

为什么呢?因为当您这样说时,let隐式的

    for i in 1...3 { // ok
        print(i)
    }

您没有说var,因此i会自动声明为let。这只是让你的生活更简单的一种方式。别担心,快乐。

答案 2 :(得分:0)

(movie, releaseDate)是一组变量。 Swift允许使用元组一次初始化多个变量。

let (movie, releaseDate) = ("Metropolis", 1927)

for-in循环是语法糖,用于重新声明集合中每个元素的常量。在这种情况下,let是隐含的。

还有其他方法可以使用隐式let获取命名常量,例如使用闭包

class MovieArchive {
    func filterByYear(year: Int, movies: [String: Int]) -> [String] {
        return movies.filter { (movie, releaseDate) -> Bool in
            year == releaseDate
            }.map { $0.key }
    }
}

顺便说一句,上面的示例给出了与代码相同的结果。

但除了for-in,func参数和闭包之外,我无法想到在Swift 3.0中省略let / var关键字的其他情况。