はじめに
この実験では、Rust のクロージャが型の匿名性を利用することを説明します。これは、クロージャを関数パラメータとして使用する際にジェネリクスを使用する必要があることを意味します。
注: 実験でファイル名が指定されていない場合は、好きなファイル名を使用できます。たとえば、
main.rs
を使用して、rustc main.rs &&./main
でコンパイルして実行できます。
This tutorial is from open-source community. Access the source code
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
この実験では、Rust のクロージャが型の匿名性を利用することを説明します。これは、クロージャを関数パラメータとして使用する際にジェネリクスを使用する必要があることを意味します。
注: 実験でファイル名が指定されていない場合は、好きなファイル名を使用できます。たとえば、
main.rs
を使用して、rustc main.rs &&./main
でコンパイルして実行できます。
クロージャは、囲むスコープから変数を簡潔にキャプチャします。これには何か結果がありますか?確かにあります。クロージャを関数パラメータとして使用するときに[ジェネリクス]が必要になることを見てみましょう。これは、それらが定義されている方法のために必要です。
// `F` はジェネリックでなければなりません。
fn apply<F>(f: F) where
F: FnOnce() {
f();
}
クロージャが定義されると、コンパイラは暗黙的に新しい匿名構造を作成して、キャプチャされた変数を内部に格納します。同時に、この未知の型に対して traits
の 1 つである Fn
、FnMut
、または FnOnce
を介して機能を実装します。この型は、呼び出しまで格納される変数に割り当てられます。
この新しい型は未知の型であるため、関数内での使用にはジェネリクスが必要になります。ただし、無制限の型パラメータ <T>
は依然として曖昧で、許可されません。したがって、traits
の 1 つである Fn
、FnMut
、または FnOnce
(それが実装しているもの)による制限は、その型を指定するのに十分です。
// `F` は、入力を取らずに何も返さないクロージャに対して `Fn` を実装する必要があります。
// これは `print` に必要なものとまったく同じです。
fn apply<F>(f: F) where
F: Fn() {
f();
}
fn main() {
let x = 7;
// `x` を匿名型にキャプチャして、それに対して `Fn` を実装します。
// それを `print` に格納します。
let print = || println!("{}", x);
apply(print);
}
おめでとうございます!あなたは型の匿名性の実験を完了しました。あなたのスキルを向上させるために、LabEx でさらに多くの実験を練習できます。