1. as
オペレーター
as
オペレータが点を除いて、Cにキャストのようなビット(それは元の型のみを使用することができi32
、i64
、f32
、
f64
、u8
、u32
、char
および他のタイプ)、それは安全です。
例
:さびでは、異なるタイプのような、暗黙的な変換値ではありません
let b: i64 = 1i32;
コンパイルエラーが促すことができるキャストではない、発生します。
error[E0308]: mismatched types
--> src\main.rs:2:18
|
2 | let b: i64 = 1i32;
| ^^^^ expected i64, found i32
help: change the type of the numeric literal from `i32` to `i64`
その後、変換として使用することができます。
let b: i64 = 1i32 as i64;
なぜそれが安全なのですか?
次のコードを試してみてください。
let b = 1i32 as char;
コンパイラエラー:
error[E0604]: only `u8` can be cast as `char`, not `i32` --> src\main.rs:2:13 | 2 | let b = 1i32 as char; | ^^^^^^^^^^^^
無関係なタイプの可視、錆も実行時エラーを回避する、変換するために拒否します。
2.形質From<T>
とInto<T>
上記いえば、as
オペレータは、それを変換する方法を、このタイプの構造体と列挙型のため、元の型に切り替えることができますか?これは、何が私たち、このセクションの内容であるFrom<T>
とInto<T>
。
これら二つの形質の構造を初めて目。
pub trait From<T> {
fn from(T) -> Self;
}
pub trait Into<T> {
fn into(self) -> T;
}
非常にシンプルな、From<T>
そこにあるfrom
方法で、Into<T>
そこにあるinto
方法。
一般的に、私達は好みを達成しようとする必要がありますFrom<T>
代わりにInto<T>
、それはあなたがあるためであるU
実現From<T>
のためにも、これは手段あなたをT
達成し、暗黙的Into<U>
。
例を見てください
fn main() {
println!("Hello, world!");
let b: Complex = 1.into();
println!("{:?}", b);
}
#[derive(Debug)]
struct Complex {
re: i32,
im: i32
}
impl From<i32> for Complex{
fn from(re: i32) -> Self {
Complex{
re,
im:0
}
}
}
私がいたときにComplex
実現するためにFrom<i32>
、後に、私はにあることができるi32
上の利用into
転換への道Complex
。
元の型を用いて達成as
遷移に対応From<T>
しますInto<T>
。
あなたはするときにU
実現するFrom<T>
あなたは失敗の可能性は、あなたがすることを選択する必要があるかのように、この遷移は、成功することを確認することを後でU
実装しますTryFrom<T>
。
ときに使用します
Into<T>
Into<T>
これは、使用場所が常にある、設計されました。何時にそれを使用するには?錆にブラッシュアップ
孤儿原则
同じクレートに宣言の型のいずれかでクレートに同じ形質とIMPLブロックまたは文:文形質とIMPL形質では、さびは孤児ルール(ルール孤児)を提供します。
それは外部の形質を達成するために、外部のタイプに関して、ないクレートに、と言うことです。
他のクレートに、1種類の形質を実装していないので、それは意図的なデザインかもしれません。
私たちは他の木枠を使用し、「任意に配置された」を強制する場合なら、それはバグを作成します。
例えば、我々は外部のライブラリLIB1とLIB2を引用し、LIB1はトレイトT宣言し、プログラムを書いた、LIB2は、構造体Sで宣言され、我々は彼らのプログラムTにSのために達成することはできません
また、これは上流の開発者の時間は特に注意して、ライブラリーを書くために他の誰かを与えることを意味します。
このような表示デバッグToStringメソッドのデフォルトとして、より一般的な標準ライブラリ特色、などのいくつかは、よくとして提供されるべきです。
そうでなければ、下流の開発者は、ライブラリを使用するために、私たちはこれらの特性を達成するのを助けるための方法はありません。
それは匿名IMPLであれば同様に、次にブロックIMPL型自体は同じモジュール内に存在しなければなりません。
もちろん、
From<T>
あなたがの種類の現在のクレートに達成したいとき、現在のクレートに属さないT
クレートの別の型への変換U
、あなたがすることを選択した場合、時間、U
実装From<T>
による孤児の原則に、コンパイラがそうすることを防止することができます。その後、我々はして選択することができますT
実装しますInto<U>
。注意、および
From<T>
異なる、実現するためにInto<U>
後に暗黙的に実装していないFrom<T>
この時点に特別な注意を要します。From<T>
魔法のようなリコールさび
?
戻り値のために使用されるオペレーター、Result<T,E>
またはOption<T>
機能。それがどのように処理されるかを思い出してくださいErr(E)
に。fn apply() -> Result<i32,i32> { Err(1) } fn main() -> Result<(),i64> { let a = apply()?; Ok(()) }
上記の例ではサビので、数値型に暗黙的とき返し、その後、変換されていないでコンパイルされた
Err(i32)
時刻が変換する方法であるErr(i64)
ことを?実際には、これは錆でシンタックスシュガーです。次のような拡張されたコード:fn apply() -> Result<i32,i32> { Err(1) } fn main() -> Result<(),i64> { let a = match apply() { Ok(v) => v, Err(e) => return Err(i64::from(e)), }; Ok(()) }
つまり、錆は自動的に対象のクラスを呼び出します
from
変換するために、方法を。
3.ポリモーフィック力間接参照
一例では、この一見:
fn print(message: &str) {
println!("{}",message);
}
fn main() {
let message: String = "message".to_string();
print(&message);
}
print
パラメータがある&str
タイプ、しかしmain
、私は渡されたが、それはある&String
引数の型。明らかに、これらの2つのタイプが同じではありません!!なぜ、錆、このコードを渡すのだろうか?
はい、これは解決策錆強制的多型への参照です。
まず、我々は理解する必要がDeref
形質を。
#[lang = "deref"]
pub trait Deref {
type Target: ?Sized;
#[must_use]
fn deref(&self) -> &Self::Target;
}
deref
この方法は、戻り&Target
参照タイプ。
参照構文でリコールソリューション錆、ref
時間がスマートポインタまたは参照では、我々が使用することができます*ref
デリファレンスの道を。これは、ためのシンタックスシュガーに似ている*ref
ようにANのアプローチ、それはフルタイムで書く必要があります*(ref.deref())
。
リコールBox<T>
の使用、Box<T>
達成するために、Deref
そのderef
メソッドの戻り&T
、その後の参照を、そしてデリファレンス演算子を使用し*
、我々はスムーズな取得T
データの種類を。つまり、あなたが実装することができDeref
、間接参照演算子のオーバーロードに。
Deref
そして、このセクションの内容は、それを行う必要がありますか?
ときにT
実現しDeref<Target=U>
、必要がために&U
ローカル、あなたが提供できる&T
データの種類を、錆が自動的に呼び出されますderef
方法を、このプロセスは、何度も繰り返すことができます。
例えば、私のカスタム型のP
実装Deref<Target=String>
、我々はできる&P
に変数の型を提供&str
型変数。&P -> &String -> &str
擬似コード:&P.deref().deref()
。
戻るこのセクションの例の最初に、print(&message)
同等のはprint((&message).deref())
、単にある&str
タイプ。