일반적으로 라이브러리에 generic 유형이있는 Foo<T>
경우 T
로컬 유형 인 경우에도 다운 스트림 크레이트는 특성을 구현할 수 없습니다 . 예를 들어
( crate_a
)
struct Foo<T>(pub t: T)
( crate_b
)
use crate_a::Foo;
struct Bar;
// This causes an error
impl Clone for Foo<Bar> {
fn clone(&self) -> Self {
Foo(Bar)
}
}
놀이터에서 작동하는 (즉 오류가 발생하는) 구체적인 예를 들어,
use std::rc::Rc;
struct Bar;
// This causes an error
// error[E0117]: only traits defined in the current crate
// can be implemented for arbitrary types
impl Default for Rc<Bar> {
fn default() -> Self {
Rc::new(Bar)
}
}
(운동장)
이것은 일반적으로 상자 제작자가 다운 스트림 상자를 파괴하지 않고 특성의 (담요) 구현을 추가 할 수있게합니다. 유형이 특정 특성을 구현 해야하는지 확실하지 않은 경우에 좋지만 나중에 유형을 지정해야합니다. 예를 들어, 처음부터 특성을 구현하지 않는 일종의 숫자 유형이있을 수 있습니다 num-traits
. 이러한 특성은 나중에 근본적인 변경없이 추가 할 수 있습니다.
그러나 경우에 따라 도서관 저자는 다운 스트림 상자가 특성을 구현할 수 있기를 원합니다. 이것은 #[fundamental]
속성이 들어오는 곳 입니다. 유형에 배치 할 때 해당 유형에 대해 현재 구현되지 않은 특성은 구현되지 않습니다 (속성 변경 금지). 결과적으로, 다운 스트림 크레이트는 유형 매개 변수가 로컬 인 한 해당 유형에 대한 특성을 구현할 수 있습니다 (이 유형으로 계산할 유형 매개 변수를 결정하는 복잡한 규칙이 있습니다). 기본 유형은 주어진 특성을 구현하지 않기 때문에 일관성 특성을 유발하지 않고 해당 특성을 자유롭게 구현할 수 있습니다.
예를 들어, Box<T>
로 표시되어 #[fundamental]
있으므로 Rc<T>
위 코드와 유사한 다음 코드가 작동합니다. Box<T>
구현하지 않는 Default
(하지 않는 T
구현 Default
우리가 그렇지 않은 미래에 있기 때문에이된다고 가정 할 수 있습니다) Box<T>
기본이다. 구현 있습니다 Default
에 대한 것은 Bar
그 이후, 문제가 발생할 것이라고 Box<Bar>
이미 구현 Default
.
struct Bar;
impl Default for Box<Bar> {
fn default() -> Self {
Box::new(Bar)
}
}
(운동장)
반면에 특성은로 표시 할 수도 있습니다 #[fundamental]
. 이것은 기본 유형에 대한 이중 의미를 갖습니다. 어떤 유형이 현재 기본 특성을 구현하지 않는 경우 해당 유형이 향후에이를 구현하지 않을 것이라고 가정 할 수 있습니다 (다시 말해서 주요 변경 사항 제외). 이것이 실제로 어떻게 사용되는지 잘 모르겠습니다. 코드 (아래 링크)에서 FnMut
정규 표현식 (약 무언가)에 필요하다는 메모와 함께 기본으로 표시되어 &str: !FnMut
있습니다. regex
상자에서 사용 된 곳이나 다른 곳에서 사용 된 곳을 찾을 수 없습니다 .
이론적으로, Add
특성이 기본 (논의 된) 것으로 표시 되었다면, 이것이 아직없는 것들 사이에 추가를 구현하는 데 사용될 수 있습니다. 예를 들어, [MyNumericType; 3]
특정 상황에서 유용 할 수있는 (포인트 방식)을 추가 하는 것은 물론 ( [T; N]
기본적으로 만드는 것도 가능합니다).
원시 기본적인 유형은 &T
, &mut T
(참조 여기에 일반적인 기본 유형 모두의 데모). 표준 라이브러리에서, Box<T>
그리고 Pin<T>
또한 기본적으로 표시됩니다.
표준 라이브러리의 기본적인 특성은 Sized
, Fn<T>
, FnMut<T>
, FnOnce<T>
와 Generator
.
점을 유의 #[fundamental]
속성이 현재 불안정합니다. 추적 문제는 이슈 # 29635 입니다.
&T
,&mut T
,*const T
,*mut T
,[T; N]
,[T]
,fn
포인터와 튜플. 그리고 그것들을 모두 테스트하면 (이 코드가 이해가 안된다면 알려주십시오) 참조가 유일한 기본 프리미티브 유형 인 것 같습니다 . 흥미 롭군 다른 사람들, 특히 원시 포인터가 아닌 이유를 아는 데 관심이 있습니다. 그러나 그것은이 질문의 범위가 아닙니다.