錆型変換

1. asオペレーター

asオペレータが点を除いて、Cにキャストのようなビット(それは元の型のみを使用することができi32i64f32
f64u8u32charおよび他のタイプ)、それは安全です

:さびでは、異なるタイプのような、暗黙的な変換値ではありません

 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型自体は同じモジュール内に存在しなければなりません。

    F001からhttps://zhuanlan.zhihu.com/p/21568827

    もちろん、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タイプ。

おすすめ

転載: www.cnblogs.com/ywxt/p/11801778.html