어휘 범위를 벗어나기 전에 반드시 해야 할 정리가 있다면 defer를
사용합니다. 그 범위가 정확히 하나의 File을 소유한다면, 더 좁은
using 문으로 획득과 하위 범위, 암묵적인 닫기를 한데 묶을 수 있습니다.
정리 순서 확인하기
프로그램과 같은 위치에 defer-resources.txt라는 텍스트 파일을 만듭니다.
내용은 정확히 다음과 같습니다.
ready다음 코드를 defer-resources.tpz로 저장합니다.
function inspectNote(path: string) -> Result<(), string> {
using file = open(path)? {
defer { print("body cleanup") }
let note = file.read()?
print("note scalars: {note.scalars().length}")
}
print("resource scope closed")
Ok(())
}
match inspectNote("defer-resources.txt") {
case Ok(_) => print("done")
case Err(message) => print("error: {message}")
}검사한 뒤 실행합니다.
topaz check defer-resources.tpz
topaz run defer-resources.tpz
출력 순서는 다음과 같습니다.
note scalars: 6
body cleanup
resource scope closed
doneopen(path)?는 파일 획득을 한 번 시도합니다. 획득에 성공한 뒤에야
using이 암묵적인 닫기를 등록합니다. 본문에서 나중에 등록한 defer가
먼저 실행되고, 암묵적인 닫기가 끝난 다음에야
resource scope closed로 진행합니다.
수명을 소유하는 형식 선택하기
| 상황 | 사용할 형식 |
|---|---|
| 현재 범위에 하나의 정리 호출이나 블록이 속함 | defer call 또는 defer { ... } |
하나의 File이 하나의 하위 블록에 속함 | using file = open(path)? { ... } |
| 획득·읽기·쓰기가 정상적으로 실패할 수 있음 | Result를 반환하거나 맞춰 보고, 호환되는 함수 안에서만 ? 사용 |
| 프로그램이 실행 시점 계약을 위반함 | 복구 가능한 정리 흐름이 아니라 실행 오류로 처리 |
한 범위에 여러 defer가 있으면 마지막에 등록한 것부터 실행합니다.
return, 접미 ?, break, continue가 범위를 가로지를 때도 정리를
마친 뒤 제어가 이동합니다. using의 이름은 바꿀 수 없고 본문 안에서만
보입니다. 클로저가 File 값을 보관할 수는 있지만, using 범위가
끝날 때 암묵적인 닫기가 실행되므로 값 보관이 리소스 수명을 늘리지는
않습니다.
Result 전파와 실행 오류는 다릅니다
open이 Err를 반환하면 아직 정리가 등록되지 않은 상태입니다.
file.read()가 Err를 반환하면 접미 ?가 활성 using 범위를
가로지르므로, 등록된 정리를 마친 다음 오류가 inspectNote 밖으로
전파됩니다.
실행 오류의 약속은 더 좁습니다. 실행 오류는 평가를 중단하며, 그 뒤에
어휘 범위의 defer나 using 정리가 모두 실행된다고 언어가 보장하지
않습니다. 지연된 정리 작업 자체에서 발생한 실행 오류는 런타임의 기록·수집
정책을 따릅니다. 잡을 수 있는 값이 되거나 이미 반환 중인 Err를
대체하지는 않습니다.
흔한 수정
파일 획득을 File.open(...)으로 쓰거나 일반적인 using 프로토콜을
만들어 내지 마세요. 정확한 획득 함수는 open(path)이고, using 문은
하나의 변경 불가능한 단순 이름과 하나의 File만 받습니다.
using 본문에서 close()를 직접 호출해도 등록된 닫기 시도는 취소되지
않습니다. 닫은 뒤의 동작이나 반복 닫기는 이식 가능한 동작이 아니므로,
보통은 한 소유자가 리소스를 한 번 닫게 해야 합니다.
정확한 경계
사용자 정의 정리 프로토콜, 여러 리소스의 동시 획득, 리소스 소유권 이전, 비동기 정리, 취소 시 정리, 호스트 예외 보장, 모듈 수명 정리는 현재 토파즈 동작이 아닙니다. 생성 대상은 위 동작을 보존하거나 지원하지 않는 프로그램을 명확히 거부해야 합니다. 이 해석기 출력만으로 모든 백엔드가 같다고 주장할 수는 없습니다.
실패와 리소스에서 안내형 예제를 다시 살펴보고, Null·Option·결과·실행 오류에서 값 없음과 복구 가능한 실패를 비교하세요. 정확한 파일 연산은 파일과 리소스에서 확인할 수 있습니다.