Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

발산 함수

발산 함수(Diverging functions)는 절대 반환되지 않습니다. 이들은 빈 타입인 !를 사용하여 표시됩니다.

#![allow(unused)]
fn main() {
fn foo() -> ! {
    panic!("이 호출은 절대 반환되지 않습니다.");
}
}

다른 모든 타입들과 달리, 이 타입은 인스턴스화할 수 없습니다. 이 타입이 가질 수 있는 모든 가능한 값의 집합이 비어 있기 때문입니다. 이는 정확히 하나의 가능한 값을 갖는 () 타입과는 다르다는 점에 유의하세요.

예를 들어, 이 함수는 반환 값에 정보가 없더라도 평소와 같이 반환됩니다.

fn some_fn() {
    ()
}

fn main() {
    let _a: () = some_fn();
    println!("이 함수는 반환되며 당신은 이 줄을 볼 수 있습니다.");
}

반면 이 함수는 호출자에게 제어권을 절대 반환하지 않습니다.

#![feature(never_type)]

fn main() {
    let x: ! = panic!("이 호출은 절대 반환되지 않습니다.");
    println!("당신은 결코 이 줄을 볼 수 없을 것입니다!");
}

이것이 추상적인 개념처럼 보일 수 있지만, 실제로는 매우 유용하며 종종 편리하게 사용됩니다. 이 타입의 주요 장점은 다른 어떤 타입으로도 형변환될 수 있다는 것이며, 이는 match 분기와 같이 정확한 타입이 요구되는 상황에서 다재다능하게 만들어줍니다. 이러한 유연성 덕분에 다음과 같은 코드를 작성할 수 있습니다:

fn main() {
    fn sum_odd_numbers(up_to: u32) -> u32 {
        let mut acc = 0;
        for i in 0..up_to {
            // 이 match 표현식의 반환 타입은 "addition" 변수의 타입 때문에
// 반드시 u32여야 함에 주목하세요.
            let addition: u32 = match i%2 == 1 {
                // "i" 변수는 u32 타입이며, 이는 완벽하게 괜찮습니다.
                true => i,
                // 반면에 "continue" 표현식은 u32를 반환하지 않지만,
// 결코 반환되지 않으므로 match 표현식의 타입 요구 사항을
// 위반하지 않으며 여전히 괜찮습니다.
                false => continue,
            };
            acc += addition;
        }
        acc
    }
    println!("9 미만의 홀수들의 합: {}", sum_odd_numbers(9));
}

또한 네트워크 서버처럼 영원히 루프를 도는 함수(예: loop {})나 프로세스를 종료하는 함수(예: exit())의 반환 타입이기도 합니다.