トークン型
プライベートなコンストラクタを持つ型は、不変条件の証明として利用できます。
// Copyright 2025 Google LLC // SPDX-License-Identifier: Apache-2.0 pub mod token { // モジュール境界の内側にある、プライベートフィールドを持つ公開型。 pub struct Token { proof: () } pub fn get_token() -> Option<Token> { Some(Token { proof: () }) } } pub fn protected_work(token: token::Token) { println!("We have a token, so we can make assumptions.") } fn main() { if let Some(token) = token::get_token() { // トークンがあるので、この作業を実行できます。 protected_work(token); } else { // トークンを取得できなかったので、`protected_work` を呼び出せません。 } }
-
動機: ユーザーが特定のタスクを実行するまで、機能へのアクセスを 制限できるようにしたい。
これは、struct と module のプライバシールールを通じて、API の利用者が 自分では構築できない型を定義することで実現できます。
Newtypes も同様の方法でプライバシールールを使い、 値が実行時に不変条件を満たすことが保証されない限り、構築を 制限します。
-
問い: ここでの
proof: ()フィールドの目的は何ですか?proof: ()がなければ、Tokenにはプライベートフィールドがなくなり、 ユーザーはTokenの値を任意に構築できるようになります。実演:
mainでトークンを手動で構築してみて、コンパイルエラーを 示してください。実演:Tokenからproofフィールドを削除して、 プライベートフィールドがなければユーザーがTokenを構築できることを示してください。 -
Token型をモジュール境界 (token) の内側に置くことで、その モジュールの外側のユーザーはproofフィールドにアクセスする権限がないため、 自分でその値を構築できません。API 開発者は、これらのトークンを生成するメソッドや関数を定義できます。 ユーザーにはできません。
そのトークンは、API 開発者がそのトークンへのアクセスに対して定めた条件を 満たしたことの証明になります。
-
問い: API 開発者が、これを回避する手段を誤って持ち込んでしまうのは どのような場合でしょうか?
「シリアライズ実装」、ほかのパーサー / 「from string」実装、 または
Defaultの実装といった答えを期待します。