在下面的代码中,我创建了一个名为startTimer的函数。此功能的目的是从@IBAction收到的输入开始倒计时。我正在努力理解:
为什么我需要声明一个var secondsRemaining?为什么我需要使用self关键字才能引用
全代码
import UIKit
class ViewController: UIViewController {
let eggTimes : [String : Int] = ["Soft": 300, "Medium": 420, "Hard": 720]
var secondsRemaining: Int? // self.secondsRemaining
@IBAction func hardnessSelected(_ sender: UIButton) {
let hardness = sender.currentTitle!
let timerSeconds = eggTimes[hardness]!
startTimer(secondsRemaining: timerSeconds)
//until here the code seems to work fine
func startTimer (secondsRemaining: Int?){
//create a function called startTimer which accepts an interger as argument called secondsremaining
self.secondsRemaining = secondsRemaining
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (Timer) in
if self.secondsRemaining! > 0 {
//if the secondsRemaining >
print ("(self.secondsRemaining ?? 0) seconds")
self.secondsRemaining! -= 1
}else {
Timer.invalidate()
}
}
}
//call the function start timer and give the secondRemaining argument the value of timerSeconds
}
在此之前,我的功能类似于
func startTimer (secondsRemaining: Int?){
//create a function called startTimer which accepts an interger as argument called secondsremaining
// self.secondsRemaining = secondsRemaining
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (Timer) in
if secondsRemaining! > 0 {
//if the secondsRemaining >
print ("(secondsRemaining ?? 0) seconds")
secondsRemaining! -= 1
}else {
Timer.invalidate()
}
}
}
这会给我返回错误:
可变运算符的左侧不可变:"secondsMaining"是"let"常数
这让我问了两个问题:
- 为函数声明的所有参数都是常量吗?如果是,为什么
- 如果问题1的答案是"否",我如何将参数声明为函数中的变量
为函数声明的所有参数总是常量吗?
否,有inout
参数可以在函数体中更改。有和的var
参数,但它们在Swift 3中被删除了。
inout
参数的目的是使函数能够更改传入的参数,并使更改反映在调用方。Swift指南中的一个例子:
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
// you are able to change a and b here
a = b
b = temporaryA
}
var a = 1
var b = 2
swapTwoInts(&a, &b)
// now b is 1 and a is 2
这意味着您必须将一些可变传递给inout
参数,而不是像timerSeconds
这样的let
常量。
此外,不能在转义闭包中使用inout
,就像传递给Timer
的那个一样。请参阅答案开头的我的解释。这可能也会有所帮助。
如果您不喜欢使用类级别,可以简单地声明一个本地var
:
func startTimer (totalTime: Int?){ // I renamed the parameter
var secondsRemaining = totalTime
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (Timer) in
...
传递给Swift函数的所有参数都是常量,因此不能更改它们。如果需要,可以将一个或多个参数作为inout传递,这意味着它们可以在函数内部进行更改,这些更改反映在函数外部的原始值中。
func startTimer (secondsRemaining: inout Int){
//your code here
}
要使用它,首先需要生成一个可变整数——不能将常量整数与inout一起使用,因为它们可能会更改。您还需要使用"与"符号将参数传递给doubleInPlace;,在它的名字之前,这是一种明确的识别,你知道它被用作inout。
startTimer(secondsRemaining: &timerSeconds)