impl Trait
トレイト境界と同様に、impl Trait 構文は関数の引数や戻り値で使用できます。
// 著作権 2022 Google LLC // SPDX-License-Identifier: Apache-2.0 // 次の糖衣構文: // fn add_42_millions<T: Into<i32>>(x: T) -> i32 { fn add_42_millions(x: impl Into<i32>) -> i32 { x.into() + 42_000_000 } fn pair_of(x: u32) -> impl std::fmt::Debug { (x + 1, x - 1) } fn main() { let many = add_42_millions(42_i8); dbg!(many); let many_more = add_42_millions(10_000_000); dbg!(many_more); let debuggable = pair_of(27); dbg!(debuggable); }
impl Trait を使うと、名前を付けられない型を扱えます。impl Trait の意味は、使われる位置によって少し異なります。
-
パラメータでは、
impl Traitはトレイト境界付きの匿名ジェネリックパラメータのようなものです。 -
戻り値の型では、それはそのトレイトを実装する何らかの具体的な型を、型名を挙げずに意味します。これは、公開 API で具体的な型を公開したくない場合に便利です。
戻り値位置では型推論は難しくなります。
impl Fooを返す関数は、ソース中にそれを書かなくても、返す具体的な型を自ら決定します。collect<B>() -> Bのようにジェネリックな型を返す関数は、Bを満たす任意の型を返すことができ、呼び出し側がlet x: Vec<_> = foo.collect()のように、あるいはターボフィッシュfoo.collect::<Vec<_>>()を使って、そのうちの 1 つを選ぶ必要がある場合があります。
debuggable の型は何でしょうか。let debuggable: () = .. を試して、エラーメッセージに何が表示されるか確認してください。