rokdocs
v0.1

2.13. 타입 경로

:: 토큰 (구두점과 연산자 토큰) 으로 이어진 식별자의 연속은 어떤 항목을 가리키는 경로입니다. 본 문서에서는 타입 위치의 경로와 연관 항목 접근에 한정해 정의하며, 모듈 import 의 정확한 의미는 use 선언 에서 별도로 다룹니다.

type_path       ::= path_root ("::" path_segment)*
path_root       ::= identifier | "pkg" | "sup"
path_segment    ::= identifier type_args?
                  | identifier "::" "<" type_expr ">" "::" identifier  // assoc item

2.13.1. 모듈 경로

타입 이름이 다른 모듈에 정의되어 있으면, 그 위치까지의 모듈 경로와 타입 이름을 함께 적습니다.

rok::std::time::Duration
rok::core::collections::List
pkg::geom::Point

이때 각 식별자는 모듈이나 항목의 이름을 나타냅니다. 마지막 식별자가 타입 이름이 되고, 그 앞부분은 해당 타입을 어디서 찾을 수 있는지를 가리키는 경로 역할을 합니다.

2.13.2. 경로의 시작점

경로의 첫 식별자는 현재 모듈에서 보이는 이름이어야 합니다. 구체적으로는 자기 자식 모듈의 이름이거나, use 로 가져온 이름이거나, 컨텍스트 키워드로 시작하는 경우가 가능합니다. 컨텍스트 키워드로는 패키지 루트를 가리키는 pkg 와 부모 모듈을 가리키는 sup 이 있으며, 이들의 정확한 의미는 경로 에서 정의합니다.

2.13.3. 연관 항목 접근

:: 는 타입에 부속된 항목에 접근할 때에도 사용됩니다.

i32::MAX                  // 정수 타입의 const 항목
Point::origin()           // 정적 메서드
List::<i32>::new()        // turbofish 로 제네릭 명시
T::Output                 // 트레잇 매개변수의 연관 타입

연관 항목 접근에는 몇 가지 형태가 있습니다. 먼저 정적 메서드는 Type::method(args) 형태로 호출합니다. 연관 const 는 Type::CONSTANT 와 같이 참조하며, 연관 타입의 경우 트레잇 매개변수의 연관 타입을 T::AssocType 으로 참조합니다.

타입 별칭을 거친 경로는 별칭이 가리키는 타입의 항목을 가리킵니다. type B = S<i32>; 이면 B::mk(x) 는 S::<i32>::mk(x) 이고, type Al<T> = S<T>; 이면 Al::mk(x) 는 인자를 추론하는 S::mk(x), Al::<i32>::mk(x) 는 S::<i32>::mk(x) 입니다. 인자 없이 부른 제네릭 별칭은 별칭이 가리키는 타입의 인자가 별칭의 서로 다른 매개변수일 때만 인자를 추론에 맡기며, 그렇지 않으면 인자를 적습니다 (type Names<V> = Dict<str, V>; 에 대해 Names::<i32>::new()).

2.13.4. 완전 자격 형태 (fully qualified path)

같은 메서드 이름이 여러 트레잇과 고유 impl 양쪽에 존재해 모호하거나, 트레잇의 연관 타입을 어느 트레잇 기준으로 참조하는지 명시해야 할 때에는 완전 자격 형태를 사용합니다.

<i32 as Display>::display(42i32)
<T as Add<U>>::Output
<Self as Iterator>::next(ref self)

완전 자격 형태의 형식은 <타입 as 트레잇>::항목 입니다. 꺾쇠 괄호 안에 타입 as 트레잇 을 적고, 그 뒤에 :: 와 항목 이름이나 메서드 호출이 이어집니다. 여기서 as 는 어느 트레잇으로 보는가를 명시하는 키워드 사용입니다. 같은 as 토큰이 표현식 위치 (이항 사용) 에서는 다른 의미를 가지며, 이는 표현식 사양에서 정의합니다.

완전 자격 형태는 타입 자리 (<T as Tr>::X 를 연관 타입으로) 와 호출 자리 (<T as Tr>::m(x)) 모두에서 유효합니다. 제네릭 트레잇이면 인자까지 맞는 impl 을 고릅니다. <T as Tr<A>>::X 와 bound T: Tr<A> 아래의 T::X 는 Tr<A> impl 의 X 이며, 같은 타입의 Tr<B> impl 의 X 와 다를 수 있습니다. <Sq as Shape>::Out 같은 projection 은 함수 시그니처, static 타입, 구조체 필드, enum payload, 타입 별칭 (제네릭이든 아니든) 에서 타입, 트레잇, impl 의 선언 순서와 관계없이 유효합니다. 자격 있는 연관 타입 뒤의 호출 <T as Tr>::X::m() 은 식에서 유효합니다.

완전 자격 형태는 일반적인 사용에서는 거의 등장하지 않습니다. 모호 해소가 필요하거나 자동 추론이 실패할 때에만 명시적으로 사용합니다.

2.13.5. turbofish. 표현식 위치의 제네릭

값 위치에서 제네릭 인자를 명시할 때에는 ::<...> 형태를 사용합니다.

parse::<i32>("42")
collect::<List<f64>>(iter)

구체적으로는 함수나 메서드 이름 뒤에 ::<...> 를 붙여 그 자리의 제네릭 인자를 적습니다. 반면 타입 위치 (: 뒤, -> 뒤, as 뒤 등) 에서는 :: 없이 <...> 를 직접 씁니다.

이러한 차이가 존재하는 이유는, 값 위치에서 < 가 비교 연산자와 모호해지기 때문입니다.

2.13.6. 타입의 절대 경로

루트부터 시작하는 절대 경로는 pkg:: 로 명시합니다 (경로). 참고로 선두 :: 형태는 rok 에 존재하지 않습니다.

2.13.7. 경로와 합 타입의 결합

경로 자체는 타입 표현식 의 단순 이름 또는 경로 형태이며, 합 타입 (|) 이나 제네릭 적용 (<...>) 등 다른 결합자와 자유롭게 섞을 수 있습니다.

rok::std::io::Result<T>
pkg::Foo | rok::std::Bar
List<rok::core::Range<i32>>

우선순위는 타입 표현식 에서 정의한 대로 적용됩니다. 즉 경로 (::) 와 제네릭 적용 (<...>) 이 합 타입 (|) 보다 더 강하게 묶입니다.

2.13.8. 빈 경로와 단독 ::

빈 경로 (:: 만 있고 식별자가 없는 경우) 는 항상 컴파일 에러입니다. 마찬가지로 :: 가 식별자 사이에 연속으로 등장하는 형태 (A::::B) 역시 에러로 처리됩니다.

GitHub에서 이 페이지 고치기