我是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)
提前感谢您的任何帮助:)
答案 0 :(得分:1)
Swift会使用movie
初始化releaseDate
和let
,但会简化初始化,以便您可以假设它们已从movies
设置为正确的变量循环迭代的时间。这就是为什么你不需要在movie
和releaseDate
之前写一下。
如果在变量前面写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
关键字的其他情况。