defer 표현식은 현재 스코프에서 나가기 직전까지 코드 실행을 딜레이합니다. defer 표현식을 사용하여 변수 리셋 등의 수정 작업을 처리할 수 있습니다. return 또는 break처럼 현재 스코프에서 조기에 나가는 경우 defer 블록의 표현식은 나가기 전에 defer 와 조우하는 한 실행됩니다.
다음 코드는 defer 를 사용하여 변수를 0으로 리셋하면서 같은 변수를 return 값으로 사용하는 방법을 보여줍니다. 이 함수에서는 RoundScore 가 반환되고 defer 블록의 표현식이 그 직후 실행됩니다.
따라서 RoundScore 값이 0으로 리셋되기 전에 이를 저장할 임시 변수를 만들지 않아도 됩니다.
OnRoundEnd<public>() : void =
var ScoreThisRound : int = AddRoundScoreToTotalScore()
Print("Points scored this round: {ScoreThisRound}")
<# TotalScore에 RoundScore를 추가하고 RoundScore를 0으로 리셋합니다.
추가된 RoundScore를 반환합니다. #>
AddRoundScoreToTotalScore<public>() : int =
defer:
set RoundScore = 0
UpdateUI()
set TotalScore += RoundScore
return RoundScore
defer 표현식 사용
defer 표현식은 block, loop, for, if, branch, 심지어 다른 defer 까지 어떤 순차 코드 블록에서든 사용할 수 있습니다.
defer 블록 내의 표현식은 즉시여야 하며 비동기화가 아니어야 하지만 예외가 하나 있습니다. 비동기화 표현식은 다음을 사용하여 즉시로 변경되면 defer 내에서 사용될 수 있습니다.
- spawn
branch(defer가 동시실행루틴 등 비동기화 블록에 있는 경우)
defer 는 결과가 없으며 실행인자 또는 할당 값으로 사용될 수 없습니다.
| defer | 나가기 전 defer |
|---|---|
|
|
이미지를 클릭하면 확대됩니다. |
이미지를 클릭하면 확대됩니다. |
defer 표현식은 조기 나가기가 발생하기 전에 조우되는 경우에만 실행됩니다.
| 조기 반환이 있는 defer | 취소된 비동기화 표현식이 있는 defer |
|---|---|
|
|
이미지를 클릭하면 확대됩니다. |
이미지를 클릭하면 확대됩니다. |
같은 스코프 내에서 나타나는 다수의 defer 표현식은 누적됩니다. 실행되는 순서는 조우되는 순서의 역순, 즉 선입 후출(first-in-last-out , FILO)입니다. 주어진 스코프 내에서 마지막으로 조우된 defer 가 먼저 실행되므로, 마지막으로 조우된 defer 내부의 표현식은 먼저 조우되고 나중에 실행될 다른 defer 표현식에 의해 수정될 변수 등의 컨텍스트를 참조할 수 있습니다.
| 한 코드 블록 내 다수의 defer 표현식 | 여러 코드 블록 내 다수의 defer 표현식 |
|---|---|
|
|
이미지를 클릭하면 확대됩니다. |
이미지를 클릭하면 확대됩니다. |
조기 나가기는 해당 나가기가 컨트롤을 defer 스코프 밖으로 이전하지 않는 한 defer 블록 내에서 허용됩니다. 예를 들어 break 가 있는 루프를 사용하는 것은 defer 내에서 허용되지만 이 break 는 코드 실행을 defer 블록 내로 유지해야 합니다. defer 블록 외부의 loop 를 참조할 수는 없습니다.
defer 의 외부 중첩 스코프에서 조우된 변수는 해당 defer 표현식 내에서 사용될 수 있습니다.
defer 는 스코프를 나가는 시점에 마지막으로 실행된다는 점을 기억하세요. 따라서 defer 가 조우된 시점이 아니라, 변수 값을 포함하여 스코프를 나가는 시점의 프로그램 스테이트를 사용합니다. 아래 코드는 10 을 출력합니다. MyScore 가 10 으로 설정된 직후에 defer 가 실행되기 때문입니다.
var MyScore = 5
defer:
Print(MyScore)
set MyScore = 10
defer 표현식을 스코프 내에서 마지막 표현식으로 사용하는 것은 전혀 사용하지 않는 것과 같습니다. 예를 들어 다음 두 표현식 세트는 똑같은 순서로 실행되므로 defer 가 필요하지 않습니다.
| defer 불포함 | defer 포함 |
|---|---|
|
|