Upgrade to Pro — share decks privately, control downloads, hide ads and more …

tonicの実装から学ぶトレイトとブランケット実装

Avatar for saw saw
January 23, 2025
160

 tonicの実装から学ぶトレイトとブランケット実装

Avatar for saw

saw

January 23, 2025

Transcript

  1. 型に対して、トレイトを実装することができる トレイトとは pub struct Post { pub username: String, pub

    content: String, } impl Summary for Post { fn summarize(&self) -> String { format!("{}: {}", self.username, self.content) } }
  2. 1.デフォルト実装を持たせることができる インターフェースとの違い pub trait Summary { fn summarize(&self) -> String

    { String::from("(Read more...)") } } 2. 既存の型に対しても、継承関係なしに実装を加えることができる
  3. message Point {} message Feature {} service Client { rpc

    GetFeature(Point) returns (Feature); } tonic clientにおけるトレイト pub struct Point {} pub struct Client {} impl Client { fn get_feature(&self, r: impl tonic::IntoRequest<Point>) {} } tonicでは以下のようなprotoから、右のコードが自動生成されます get_featureはIntoRequest<Point>を引数に要求しています
  4. トレイトの制約を満たすあらゆる型に対して、トレイトを実装することができる ブランケット実装 impl<T> IntoRequest<T> for Request<T> { fn into_request(self) ->

    Request<T> { self } } impl<T> IntoRequest<T> for T { fn into_request(self) -> Request<Self> { Request::new(self) } } 全ての型TとRequest<T>に対してIntoRequestを実装している そのため、PointとRequest<Point>をget_featureに渡すことができる
  5. Axumのハンドラーは関数を定義するといい感じにRouterに渡すことができる おまけ pub async fn hoge_handler( Json(request): Json<HogeRequest>, ) ->

    Result<Json<HogeResponse>, Error> { // ... } pub async fn fuga_handler( Path(fuga_id): Json<string>, ) -> Result<Json<FugaResponse>, Error> { // ... } ブランケット実装(とマクロ)によって、関数(FnOnce)に対してハンドラのトレイトを 実装しています