通常、ライブラリにジェネリック型がある場合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
ポインタとタプル。そして、それらすべてをテストします(このコードが意味をなさないかどうか教えてください)参照が唯一の基本的なプリミティブ型のようです。面白い。他の人がそうではない理由、特に生のポインタを知りたいと思います。しかし、それはこの質問の範囲ではないと思います。