프로그램 구조

Defer와 리소스

`defer`와 File 전용 `using` 구문의 사용 기준을 파악하고, 리소스 정리 순서 및 실행 오류 경계를 이해합니다.

일반적인 스코프 종료 정리에는 defer를 사용합니다. 소유한 File 하나에는 using을 사용해 리소스 획득, 하위 스코프의 사용, 암묵적 닫기를 통한 정리를 결합합니다.

정리 순서 확인하기

프로그램과 동일한 위치에 defer-resources.txt라는 텍스트 파일을 만듭니다. 내용은 다음과 같습니다.

ready

다음 코드를 defer-resources.tpz로 저장합니다.

TOPAZ
function 메모검사(경로: string) -> Result<(), string> {
    using 파일 = open(경로)? {
        defer { print("body cleanup") }
        let 메모 = 파일.read()?
        print("note scalars: {메모.scalars().length}")
    }

    print("resource scope closed")
    Ok(())
}

match 메모검사("defer-resources.txt") {
    case Ok(_) => print("done")
    case Err(메시지) => print("error: {메시지}")
}

코드를 검사한 뒤 실행합니다.

BASH
topaz check defer-resources.tpz
topaz run defer-resources.tpz

출력 순서는 다음과 같습니다.

출력
note scalars: 6
body cleanup
resource scope closed
done

open(경로)?는 파일 획득을 한 번만 시도합니다. 획득에 성공한 후에야 using 문이 암묵적 닫기 동작을 등록합니다. 본문 내에서 나중에 등록된 defer 블록이 먼저 실행되며, 암묵적 닫기까지 완료된 후에 resource scope closed로 넘어갑니다.

수명을 소유하는 형식 선택하기

상황사용할 형식
현재 범위에 하나의 정리 호출이나 블록이 속한 경우defer call 또는 defer { ... }
하나의 File이 하나의 하위 블록에 속한 경우using 파일 = open(경로)? { ... }
획득·읽기·쓰기가 정상적으로 실패할 수 있는 경우Result를 반환하거나 분기 처리하고, 호환되는 함수 내부에서만 ? 사용
프로그램이 런타임 계약을 위반하는 경우복구 가능한 정리 흐름이 아니라 실행 오류로 처리

단일 범위 내에 defer 구문이 여러 개 있으면 마지막에 등록된 것부터 역순으로 실행합니다. return, 접미사 ?, break, continue가 범위를 가로지를 때도 정리 작업을 먼저 마친 후 제어가 이동합니다. using 문으로 생성된 이름은 변경할 수 없으며 본문 내부에서만 유효합니다. 클로저가 File 값을 보관하는 것은 가능하지만, using 범위가 종료되면 암묵적 닫기가 실행됩니다. 해당 값을 계속 참조하더라도 리소스 수명이 연장되지는 않습니다.

Result 전파와 실행 오류는 다릅니다

openErr를 반환하면 아직 등록된 정리 작업이 없습니다. 파일.read()Err를 반환하는 경우는 다릅니다. 접미사 ? 연산자가 활성화된 using 범위를 가로지르므로, 등록된 정리 작업을 마친 뒤 오류가 메모검사 외부로 전파됩니다.

실행 오류는 평가를 즉시 중단합니다. 그 시점 이후 어휘 범위의 deferusing 정리 동작은 지정되어 있지 않습니다. 지연 정리 작업에서 발생한 실행 오류는 런타임 기록·수집 정책을 따릅니다. 이 오류는 포착 가능한 값이 아니며, 이미 반환 중인 Err는 그대로 유지됩니다.

흔한 수정

파일 획득에 File.open(...)을 사용하지 마세요. 임의의 using 프로토콜을 새로 정의하지도 마세요. 올바른 획득 함수는 open(path) 하나뿐입니다. using 문은 불변인 단일 이름 하나와 File 하나만 받습니다.

using 본문 내부에서 close()를 직접 호출하더라도 등록된 닫기 시도가 취소되지는 않습니다. 닫은 이후의 동작이나 중복 닫기는 이식성을 제공하지 않으므로, 보통은 단일 소유자가 리소스를 한 번만 닫도록 구현해야 합니다.

정확한 경계

현재 토파즈 리소스 동작은 위에서 설명한 File, defer, using 연산을 다룹니다. 사용자 정의 정리 프로토콜, 다중 리소스 획득, 리소스 소유권 이전, 비동기 정리, 취소 시 정리, 호스트 예외 정리, 모듈 수명주기 정리는 향후 결정 대상입니다. 생성 타깃은 문서의 동작을 유지하거나 산출물 출력 전에 거부합니다. 타깃별 동작은 사용할 타깃에서 확인하세요.

실패와 리소스에서 안내형 예제를 다시 살펴보세요. Null·Option·결과·fault에서는 값 없음과 복구 가능한 실패를 비교합니다. 정확한 파일 연산은 파일과 리소스에서 확인할 수 있습니다.