예외: try...finally 식(F#)
try...finally 식을 사용하면 코드 블록에서 예외를 throw하는 경우에도 정리 코드를 실행할 수 있습니다.
try
expression1
finally
expression2
설명
try...finally 식을 사용하면 expression1을 실행하는 동안 예외가 발생하는지 여부와 상관없이 위 구문의 expression2에 있는 코드를 실행할 수 있습니다.
expression2의 형식은 전체 식의 값에 영향을 주지 않습니다. 예외가 발생하지 않았을 때 반환되는 형식은 expression1의 마지막 값입니다.예외가 발생하면 어떠한 값도 반환되지 않습니다. 이 경우 호출 스택을 거슬러 올라가며 다음 번 일치하는 예외 처리기로 제어 흐름이 이관됩니다.어떠한 예외 처리기도 찾지 못하면 프로그램이 종료됩니다.일치하는 처리기의 코드를 실행하거나 프로그램이 종료되기에 앞서 finally 분기의 코드가 실행됩니다.
다음 코드에서는 try...finally 식을 사용하는 방법을 보여 줍니다.
let divide x y =
let stream : System.IO.FileStream = System.IO.File.Create("test.txt")
let writer : System.IO.StreamWriter = new System.IO.StreamWriter(stream)
try
writer.WriteLine("test1");
Some( x / y )
finally
writer.Flush()
printfn "Closing stream"
stream.Close()
let result =
try
divide 100 0
with
| :? System.DivideByZeroException -> printfn "Exception handled."; None
콘솔에 출력되는 결과는 다음과 같습니다.
Closing stream
Exception handled.
이 출력에서 알 수 있듯이 외부 예외를 처리하기 전에 스트림이 닫히고 파일 test.txt에는 텍스트 test1이 포함됩니다. 이는 예외로 인해 제어 흐름이 외부 예외 처리기로 이관되더라도 버퍼가 플러시되고 디스크에 기록되었음을 의미합니다.
try...with 구문은 try...finally 구문과 다른 별도의 구문입니다.따라서 코드에 with 블록과 finally 블록이 둘 다 필요하면 다음 코드 예제에서와 같이 두 구문을 중첩해야 합니다.
exception InnerError of string
exception OuterError of string
let function1 x y =
try
try
if x = y then raise (InnerError("inner"))
else raise (OuterError("outer"))
with
| InnerError(str) -> printfn "Error1 %s" str
finally
printfn "Always print this."
let function2 x y =
try
function1 x y
with
| OuterError(str) -> printfn "Error2 %s" str
function2 100 100
function2 100 10
시퀀스 식과 비동기 워크플로를 포함한 계산 식의 컨텍스트에서 try...finally 식을 사용자 지정하여 구현할 수 있습니다.자세한 내용은 계산 식(F#)을 참조하십시오.