<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rust Tech</title>
	<atom:link href="https://rust-tech.nkhn37.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://rust-tech.nkhn37.net</link>
	<description>Rustプログラミング学習サイト</description>
	<lastBuildDate>Sat, 04 Apr 2026 20:27:56 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://rust-tech.nkhn37.net/wp-content/uploads/2025/06/cropped-lion-preasure-clear-32x32.png</url>
	<title>Rust Tech</title>
	<link>https://rust-tech.nkhn37.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【Rust入門】Iteratorの消費アダプタ（sum・fold・collect など）を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-iterator-consuming-adapters/</link>
					<comments>https://rust-tech.nkhn37.net/rust-iterator-consuming-adapters/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[イテレータ]]></category>
		<category><![CDATA[イテレータアダプタ]]></category>
		<category><![CDATA[消費アダプタ]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1891</guid>

					<description><![CDATA[Rust の イテレータ（Iterator）に用意されている消費アダプタの基本を初心者にも分かりやすく解説します。 イテレータの消費とは イテレータ（Iterator）とは、値の列を生成する値で、要素を順番に取り出すこと [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust の イテレータ（Iterator）に用意されている<span class="jinr-d--text-color d--marker1 d--bold">消費アダプタの基本</span>を初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">イテレータの消費とは</h2>



<p>イテレータ（Iterator）とは、値の列を生成する値で、要素を順番に取り出すことができる仕組みです。イテレータの基本やイテレータアダプタについて理解が不十分な方は、以下にまとめていますので参考にしてください。</p>



<ul class="wp-block-list jinr-list">
<li><a href="https://rust-tech.nkhn37.net/rust-iterator-basic/" target="_blank" rel="noreferrer noopener">イテレータ（Iterator）の基本を分かりやすく解説</a></li>



<li><a href="https://rust-tech.nkhn37.net/rust-iterator-adapters/" target="_blank" rel="noreferrer noopener">Iterator のアダプタ（map・filter など）を分かりやすく解説</a></li>
</ul>



<p>上記では、イテレータの基本とアダプタを使って別のイテレータを作る方法を紹介しました。</p>



<p>イテレータは、<code>next</code> を使って順に値を取り出すことができます。<code>next</code> を繰り返し呼び出すことで、イテレータの要素を最後まで（または途中まで）使い切ることを「消費」と言います。イテレータを消費しつつ、最終的な計算結果を得るメソッドを「<span class="jinr-d--text-color d--marker1 d--bold">消費アダプタ（consuming adapter）</span>」と言います。</p>



<p>この記事では、代表的な消費アダプタを紹介しつつ、<span class="jinr-d--text-color d--marker1 d--bold">イテレータを消費する方法</span>を紹介します。</p>



<div id="nkhn3-2263845447" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">代表的な消費アダプタ</h2>



<p>以降では、よく使用される代表的な消費アダプタを紹介していきます。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>collect</code>：コレクションに集約する</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>collect</code></span> は、イテレータの要素をコレクションにまとめることができる消費アダプタです。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>Vec</code> への集約</h4>



<p>以下は、<code>numbers</code> を 2 倍した数値列を <code>Vec</code> に集約する例です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // map を適用したイテレータを collect して新しい Vec に集約
    let result_vec: Vec&lt;_> = numbers.iter().map(|x| x * 2).collect();

    // 結果を表示
    println!("{:?}", result_vec);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
[2, 4, 6, 8, 10]</pre>



<p>例で「<code>numbers.iter().map(|x| x * 2)</code>」は、map というイテレータアダプタを使い、各要素を 2 倍したイテレータを返します。この段階では、<code>x * 2</code> の計算は適用されていません。その後、<code>collect</code> という消費アダプタが適用されることで計算が実行されて <code>Vec</code> の <code>result_vec</code> にまとめられます。</p>



<p>なお、collect は、任意のコレクションにまとめることができるため「<code>result_vec: Vec&lt;i32&gt;</code>」という型注釈をつけるか、「<code>collect::&lt;Vec&lt;_&gt;&gt;()</code>&nbsp;」のようにどの型に変換するかを明示する必要があります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">その他のコレクションへの集約</h4>



<p>上記で <code>Vec</code> への集約を紹介しましたが、任意のコレクションにまとめられると説明しました。1 例として <code>HashSet</code> に集約する例を見ておきましょう。</p>



<p>以下は、<code>numbers</code> の 値を 2 倍にした後、<code>HashSet</code> に集約しています。<code>HashSet</code> を用いると、重複を取り除いた集合として扱うことができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::collections::HashSet;

fn main() {
    let numbers = vec![1, 2, 3, 1, 2, 5];

    // HashSet を使用して、重複を排除したコレクションに集約
    let result_set: HashSet&lt;_> = numbers.iter().map(|x| x * 2).collect();

    // 結果を表示
    println!("{:?}", result_set);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果例】※ HashSet は順序保証がされないため、順序は実行により異なります
{4, 2, 6, 10}</pre>



<p>型注釈で「<code>: HashSet&lt;_&gt;</code>」を付けることで、<code>HashSet</code> に集約できます。このように、<code>collect</code> は変換先のコレクションの型によって結果が変わることが特徴的です。</p>



<p>省略しますが、同様に <code>HashMap</code> などのその他コレクションも同様に扱うことができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">無限のシーケンスの場合</h4>



<p>イテレータの強力な特徴は、無限のデータシーケンスも扱うことができる点です。ただし、<code>collect</code> を使用する場合には、注意が必要です。以下のように <code>take</code> や <code>take_while</code> などで、データの範囲を制限して適用をする必要があります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // 無限の数値列を生成するイテレータ
    let infinite_numbers = 1..;

    // 無限の数値列から最初の 5 個を collect して Vec に集約
    let result_vec: Vec&lt;_> = infinite_numbers.take(5).collect();

    // 結果を表示
    println!("{:?}", result_vec);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
[1, 2, 3, 4, 5]</pre>



<p>例では「<code>1..</code>」により、<code>RangeFrom&lt;i32&gt;</code> のイテレータを生成しています。このイテレータは 1 から順番に数値を取り出せますが、末尾が決まっていません。そのため、<code>take</code> により先頭 5 個を取り出すイテレータアダプタを適用してから <code>collect</code> を適用しています。</p>



<p>無限のデータシーケンスの場合は、消費アダプタの使用には注意が必要です。以降で紹介する消費アダプタについても同様に無限に続くイテレータの場合は注意して使用してください。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>count</code>：件数を取得する</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>count</code></span> は、イテレータの要素数を取得する消費アダプタです。<code>count</code> はイテレータを消費し、要素を最後まで走査することで件数を返します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // count() メソッドを使用して、イテレータの要素数を数える
    let count = numbers.iter().count();

    // 結果を表示
    println!("{}", count);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
5</pre>



<h3 class="wp-block-heading jinr-heading d--bold"><code>sum</code> / <code>product</code>：数値の合計や積を計算する</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>sum</code></span> は要素の合計、<span class="jinr-d--text-color d--marker1 d--bold"><code>product</code></span> は要素の積を計算するための消費アダプタです。これらは、数値を集約したいときに便利です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = [1, 2, 3, 4, 5];

    let sum: i32 = numbers.iter().sum();
    let product: i32 = numbers.iter().product();

    println!("sum: {}", sum);
    println!("product: {}", product);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
sum: 15
product: 120</pre>



<p><code>sum</code> や <code>product</code> は、戻り値の型をコンパイラが決められないため、基本的には型注釈が必要になります（例「<code>sum : i32</code>」）。ただし、関数の戻り値型などから型が明らかな場合は、型推論により型注釈を省略できることもあります。なお、<code>sum</code> は数値型に対してのみ使用可能です。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>max</code> / <code>min</code>：最大値や最小値を取得する</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>max</code></span> と <span class="jinr-d--text-color d--marker1 d--bold"><code>min</code></span> は、それぞれ最大値・最小値を取得するための消費アダプタです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = [3, 2, 5, 1, 4];

    // 最大値と最小値を求める
    let max = numbers.iter().max();
    let min = numbers.iter().min();

    // 結果を表示
    println!("max: {:?}", max);
    println!("min: {:?}", min);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
max: Some(5)
min: Some(1)</pre>



<p><code>max</code> と <code>min</code> については、戻り値が <code>Option</code> 型になる点に注意してください。これは、イテレータが空の場合は、最大値や最小値を返せないためです。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><strong>【補足：比較方法を指定する】</strong></p>



<p><code>max_by</code> や <code>min_by</code> を使用すると、比較方法を自分で指定することができます。また、<code>max_by_key</code> や <code>min_by_key</code> を使うと、キーを指定して比較することも可能です。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold"><code>fold</code> / <code>rfold</code>：畳み込み計算を行う</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>fold</code></span> や <span class="jinr-d--text-color d--marker1 d--bold"><code>rfold</code></span> は、イテレータの要素を順番に取り出しながら 1 つの値にまとめるための消費アダプタです。<code>fold</code> は前から、<code>rfold</code> は後ろから計算する点に違いがあります。</p>



<p>基本的な構文は以下のような形となります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">iterator.fold(初期値, |累積値, 要素| 処理)</pre>



<ul class="wp-block-list jinr-list">
<li>初期値：最初に累積する値</li>



<li>累積値：これまでの計算結果</li>



<li>要素：イテレータから取り出した要素</li>
</ul>



<p>以降では、簡単な合計の例で <code>fold</code> と <code>rfold</code> の使い方を見てみましょう。なお、合計を例にするだけで、<code>fold</code> / <code>rfold</code> では任意の処理ができる点が非常に強力です。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>fold</code>（前から畳み込む）</h4>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>fold</code></span> は、イテレータの要素を前から順に処理しながら、1 つにまとめます。</p>



<h5 class="wp-block-heading jinr-heading d--bold">合計 (<code>sum</code>) を <code>fold</code> で計算する例</h5>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // fold を使用して、イテレータの要素の合計を求める
    let sum = numbers.iter().fold(0, |acc, x| acc + x);

    // 結果を表示
    println!("sum: {}", sum);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
sum: 15</pre>



<p>例では、「初期値: <code>0</code>」「<code>0 + 1 = 1</code>」「<code>1 + 2 = 3</code>」…「<code>10 + 5 = 15</code>」のように計算が繰り返し進んで 1 つの合計結果にまとまります。この例から、分かるように上記で紹介した <code>sum</code> や <code>product</code> などは、<code>fold</code> でも実現することができます。</p>



<h5 class="wp-block-heading jinr-heading d--bold">任意の処理を定義可能</h5>



<p>上記では分かりやすいように合計の例を紹介しましたが、<code>fold</code> は任意の処理を定義できます。以下は、文字列を連結する例です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let words = vec!["Hello", " ", "Rust", "!"];

    // fold を使用して、イテレータの要素を連結する
    let concatenated = words.iter().fold(String::new(), |acc, word| acc + word);

    // 結果を表示
    println!("{}", concatenated);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Hello Rust!</pre>



<p>このように、<code>fold</code> は文字列の結合などにも使えます。<code>fold</code> や後述する <code>rfold</code> は要素をどのように 1 つの値へまとめるかを柔軟に定義できる点が大きな特徴です。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>rfold</code>（後ろから畳み込む）</h4>



<p>rfold は、fold と同じように値を 1 つにまとめますが、後ろから順に処理する点が異なります。数値計算だと計算順序が分かりにくいため、文字列結合で比較してみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let words = vec!["a", "b", "c", "d"];

    // fold を使用して、前から順に要素を結合する
    let forward = words.iter().fold(String::new(), |acc, word| acc + word);

    // rfold を使用して、逆順に要素を結合する
    let backward = words.iter().rfold(String::new(), |acc, word| acc + word);

    // 結果を表示
    println!("forward: {}", forward);
    println!("backward: {}", backward);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
fold: abcd
rfold: dcba</pre>



<p>例のように、<code>fold</code> では <code>"abcd"</code> のような順になりますが、<code>rfold</code> では、<code>"dcba"</code> のように処理の順序が逆になっています。数値計算などでも、処理の順序が変わる点は同様です。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><strong>【補足：エラー処理付きの畳み込み】</strong></p>



<p><code>try_fold</code> や <code>try_rfold</code> を使用すると途中でエラーが発生した場合に処理を中断することができます。</p>
</div>
		</div></section>



<h2 class="wp-block-heading jinr-heading d--bold">その他の便利な消費アダプタ</h2>



<h3 class="wp-block-heading jinr-heading d--bold">その他の消費アダプタ一覧</h3>



<p>上記で紹介した消費アダプタの他にも多くの消費アダプタがありますが、ここでは、代表的なものを一覧で簡単に紹介します。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>消費アダプタ</th><th>概要</th></tr></thead><tbody><tr><td><code>any</code> / <code>all</code></td><td>条件を満たす要素の有無を判定する。</td></tr><tr><td><code>position</code> / <code>rposition</code></td><td>条件の要素を満たす要素の位置を返す。</td></tr><tr><td><code>nth</code> / <code>nth_back</code></td><td><code>n</code> 番目の要素を取得する。<code>nth(0)</code> は <code>next()</code> と同じ。</td></tr><tr><td><code>last</code></td><td>最後の要素を取得する。</td></tr><tr><td><code>find</code> / <code>rfind</code> / <code>find_map</code></td><td>条件に一致する要素を検索する。</td></tr><tr><td><code>partition</code></td><td>条件に応じて 2 つに分割する。</td></tr><tr><td><code>for_each</code> / <code>try_for_each</code></td><td>各要素に処理を適用する。</td></tr></tbody></table></figure>



<div id="nkhn3-3794779876" class="nkhn3--2 nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust の イテレータ（Iterator）に<span class="jinr-d--text-color d--marker1 d--bold">消費アダプタの基本</span>について解説しました。</p>



<p>イテレータは <code>next</code> を使って順番に値を取り出す仕組みであり、その要素を最後まで、または途中まで使うことを「消費」と言います。消費アダプタは、そのイテレータを消費しながら最終的な結果を得るためのメソッドです。</p>



<p>この記事では、代表的な消費アダプタとして、次のようなものを紹介しました。</p>



<ul class="wp-block-list jinr-list">
<li><code>collect</code>：コレクションにまとめる</li>



<li><code>count</code>：件数を取得する</li>



<li><code>sum</code> / <code>product</code>：合計や積を計算する</li>



<li><code>max</code> / <code>min</code>：最大値や最小値を取得する</li>



<li><code>fold</code> / <code>rfold</code>：任意の処理で 1 つの値にまとめる</li>
</ul>



<p>まずは <code>collect</code>、<code>count</code>、<code>sum</code> などの基本的な消費アダプタに慣れてもらい、そのうえで <code>fold</code> を理解すると、イテレータの仕組みをより深く理解できるようになります。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/iterator-consuming-adapters" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section><div id="nkhn3-3622287659" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-iterator-consuming-adapters/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】Iterator のアダプタ（map・filter など）を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-iterator-adapters/</link>
					<comments>https://rust-tech.nkhn37.net/rust-iterator-adapters/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Tue, 31 Mar 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[filter_map]]></category>
		<category><![CDATA[flat_map]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[イテレータ]]></category>
		<category><![CDATA[イテレータアダプタ]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1886</guid>

					<description><![CDATA[Rust の イテレータ（Iterator）に用意されているイテレータアダプタの基本を初心者にも分かりやすく解説します。 イテレータアダプタとは イテレータ（Iterator）とは、値の列を生成する値で、要素を順番に取り [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust の イテレータ（Iterator）に用意されている<span class="jinr-d--text-color d--marker1 d--bold">イテレータアダプタの基本</span>を初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">イテレータアダプタとは</h2>



<p>イテレータ（Iterator）とは、値の列を生成する値で、要素を順番に取り出すことができる仕組みです。イテレータの基本は「<a href="https://rust-tech.nkhn37.net/rust-iterator-basic/" target="_blank" rel="noreferrer noopener">イテレータ（Iterator）の基本を分かりやすく解説</a>」を参考にしてください。この記事で、基本となる <code>next</code> や <code>into_iter</code> などについて解説しています。</p>



<p>イテレータには、要素を順番に取り出すだけでなく、要素を変換したり、条件に合うものだけを残したりする便利なメソッドが多数用意されています。これらを<span class="jinr-d--text-color d--marker1 d--bold">イテレータアダプタ</span>と言います。イテレータアダプタは、既存のイテレータをもとに、新しいイテレータを作り出します。</p>



<p>イテレータアダプタの重要な点は、その場ですぐに最終結果を作るのではなく、新しいイテレータを返すという点です。この仕組みは「遅延評価」と呼ばれ、要素が実際に取り出されるときに初めて処理が実行されます。そのため、必要な分だけ効率よく処理を行うことができます。</p>



<p>また、イテレータアダプタには、変換などの処理内容を指定するためにクロージャをよく使用します。なお、クロージャの代わりに通常関数を渡すことも可能ですが、外部変数を利用できる点からクロージャがよく使用されます。</p>



<p>この記事では、代表的なイテレータアダプタを紹介しつつ、イテレータアダプタの基本的な使い方を紹介していきます。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>クロージャの基本については「<a href="https://rust-tech.nkhn37.net/rust-closure-basic/" target="_blank" rel="noreferrer noopener">クロージャの基本と使い方を分かりやすく解説</a>」を参考にしてください。</p>
</div>
		</div></section>



<div id="nkhn3-475874880" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">代表的なイテレータアダプタ</h2>



<p>ここでは、基本としてよく使用するイテレータアダプタである <code>map</code> と <code>filter</code> を中心に使い方を見ていきましょう。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>map</code>：各要素に処理を適用し、別の値に変換する</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>map</code></span> は、イテレータの各要素に対して指定した処理を適用し、その結果となるイテレータに変換するアダプタです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // 元データのベクタを作成
    let numbers = vec![1, 2, 3];

    // map を使用し、各要素を2倍にしたイテレータを作成
    // (この時点ではまだ計算されない)
    let doubled_iter = numbers.iter().map(|x| x * 2);

    // イテレータをベクタに収集 (ここで初めて計算が行われる)
    let result: Vec&lt;_> = doubled_iter.collect();

    // 結果を表示
    println!("{:?}", result);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
[2, 4, 6]</pre>



<p><code>map</code> では、引数にクロージャ（または関数）を受け取りイテレータを返却します。上記で <code>doubled_iter</code> はイテレータです。この時点では、各要素を 2 倍にするという計算はまだされていません。<code>collect</code> や <code>for</code> 文で要素を取り出すときに、初めて計算が実行されます。これが「遅延評価」です。</p>



<p><code>result</code> 変数に束縛する際に使用している <code>collect</code> という処理は、イテレータの要素をコレクションにまとめるメソッドです。<code>collect</code> は戻り値の型が一意には決まりません。例えば、<code>Ve</code>c や <code>HashSet</code> などのさまざまなコレクションに変換できるためです。このため「<code>let result: Vec&lt;_&gt;</code>」のように型注釈をつけるか、<code>collect::&lt;Vec&lt;_&gt;&gt;()</code> のように、どの型に変換するかを明示する必要があります</p>



<p>なお、上記では <code>map</code> によるイテレータ生成から、<code>collect</code> による遅延評価での処理という流れを理解してもらうために丁寧に文を分けて記載しましたが、以下のように「<code>.</code>（ドット）」で処理を連結させることで簡潔に記載も可能です。以降では、この形式で紹介していきます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // 元データのベクタを作成
    let numbers = vec![1, 2, 3];

    // map を使用し、各要素を2倍にした結果を取得する
    let result: Vec&lt;_> = numbers.iter().map(|x| x * 2).collect();

    // 結果を表示
    println!("{:?}", result);
}</pre>



<h3 class="wp-block-heading jinr-heading d--bold"><code>filter</code>：条件に一致する要素だけを残す</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>filter</code></span> は、イテレータの各要素に対して条件による判定をし、条件に一致する要素だけを残したイテレータに変換するアダプタです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // filter を使用し、偶数のみを残す
    let even_numbers: Vec&lt;_> = numbers.iter().filter(|x| **x % 2 == 0).collect();

    // 結果を表示
    println!("{:?}", even_numbers);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
[2, 4, 6, 8, 10]</pre>



<p><code>filter</code> では、クロージャが <code>true</code> を返した要素のみ残り、<code>false</code> の要素は除外されます。</p>



<p>例では、<code>iter()</code> を使用しているため要素は参照として扱われます。また、<code>filter</code> は要素をクロージャに渡して条件判定を行うため、この例では <code>**x</code> のように参照を外して値を取り出しています。（参照が重なっているため、2 回参照を外しています。）</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>map</code> と <code>filter</code> を組み合わせて使う</h3>



<p>イテレータアダプタは、「<code>.</code>（ドット）」でつなげることで複数の処理を連続して適用することで本領を発揮します。以下は、<code>filter</code> で偶数のみ残し、さらに <code>map</code> で 2 倍する例です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // filter と map を組み合わせて、偶数の2倍を計算する
    let even_doubles: Vec&lt;_> = numbers
        .iter()
        .filter(|x| **x % 2 == 0)
        .map(|x| x * 2)
        .collect();

    // 結果を表示
    println!("{:?}", even_doubles);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
[4, 8, 12, 16, 20]</pre>



<p>このように、イテレータアダプタを組み合わせて、データの処理を上から順に記述していくことで、可読性が高いコードを記述できることが特徴です。</p>



<h2 class="wp-block-heading jinr-heading d--bold">その他の便利なイテレータアダプタ</h2>



<p><code>map</code> と <code>filter</code> はイテレータアダプタとして中心的なものです。他にも多くのイテレータアダプタがありますが、ここではよく使われるものをいくつか紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>filter_map</code>：変換を行い、成功（<code>Option</code> の <code>Some</code>）のみを残す</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>filter_map</code></span> は、変換と絞り込みを同時に行うことができるアダプタで、変換を行い成功した値のみを残すことができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let values = vec!["10", "abc", "20", "def", "30"];

    // filter_map を使用して、文字列を整数に変換し、成功したものだけを収集する
    let numbers: Vec&lt;_> = values
        .iter()
        .filter_map(|s| s.parse::&lt;i32>().ok())
        .collect();

    // 結果を表示
    println!("{:?}", numbers);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
[10, 20, 30]</pre>



<p>この例では、文字列の <code>Vec</code> を整数に変換しています。指定したクロージャは、整数に変換できた場合は、<code>Option</code> 型の <code>Some(v)</code> を返し、変換できなかった場合は <code>None</code> を返します。</p>



<p>結果を見ると分かるように <code>filter_map</code> は、変換結果が <code>Some(v)</code> であれば中の値 <code>v</code> を結果に残し、<code>None</code> の場合はその値を除外します。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>flat_map</code>：各要素を複数の要素に展開し、1 つの列としてつなげる</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>flat_map</code></span> は、各要素を複数の要素に展開し、1 つの列としてつなげるアダプタです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let numbers = vec![1, 2, 3];

    let result: Vec&lt;_> = numbers.iter().flat_map(|x| vec![*x, *x * 10]).collect();

    // 結果を表示
    println!("{:?}", result);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
[1, 10, 2, 20, 3, 30]</pre>



<p>この例で、指定したクロージャは与えられたイテレータの要素の値に対して、値と 10 倍の値のペアを生成しています。<code>[1, 2, 3]</code> がクロージャにより <code>[[1, 10], [2, 20], [3, 30]]</code> に展開され、<code>flat_map</code> により <code>[1, 10, 2, 20, 3, 30]</code> に 1 つの列につなげられているイメージを持ってもらうと分かりやすいかと思います。</p>



<h3 class="wp-block-heading jinr-heading d--bold">その他のイテレータアダプタ一覧</h3>



<p>上記で紹介したイテレータアダプタの他にも多くのイテレータアダプタがありますが、ここでは、代表的なものを一覧で簡単に紹介します。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>イテレータアダプタ</th><th>概要</th></tr></thead><tbody><tr><td><code>flatten</code></td><td>ネストした構造を平坦化する</td></tr><tr><td><code>take</code></td><td>先頭から指定した数だけ取得する</td></tr><tr><td><code>take_while</code></td><td>条件を満たす間だけ先頭から取得する</td></tr><tr><td><code>skip</code></td><td>先頭から指定した数だけをスキップする</td></tr><tr><td><code>skip_while</code></td><td>条件を満たす間だけ先頭からスキップする</td></tr><tr><td><code>enumerate</code></td><td>インデックス付きで取得する</td></tr><tr><td><code>zip</code></td><td>複数のイテレータを組み合わせて取得する（短い方にあわせて終了する）</td></tr></tbody></table></figure>



<div id="nkhn3-2635148667" class="nkhn3--2 nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust の イテレータに用意されている<span class="jinr-d--text-color d--marker1 d--bold">イテレータアダプタの基本</span>について解説しました。</p>



<p>イテレータアダプタは、既存のイテレータから新しいイテレータを作る仕組みです。代表的なイテレータアダプタである <code>map</code> と <code>filter</code> を用いて基本的な使い方を紹介しています。また、その他のイテレータアダプタについても簡単に紹介しました。</p>



<p>イテレータアダプタは、組み合わせて使用することで、処理の流れを非常に分かりやすく記述することができます。まずは、<code>map</code> と <code>filter</code> でしっかりと理解してもらうことが重要です。その上で、<code>filter_map</code> や <code>flat_map</code> などのさまざまなアダプタも徐々に使えるようになっていってください。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては&nbsp;<a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/iterator-adapters" target="_blank" rel="noreferrer noopener">GitHub</a>&nbsp;にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section>


<p></p>
<div id="nkhn3-26348173" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-iterator-adapters/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】イテレータ（Iterator）の基本を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-iterator-basic/</link>
					<comments>https://rust-tech.nkhn37.net/rust-iterator-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Thu, 19 Mar 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[IntoIterator]]></category>
		<category><![CDATA[Iterator]]></category>
		<category><![CDATA[トレイト]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1884</guid>

					<description><![CDATA[Rust におけるイテレータ（Iterator）の基本を初心者にも分かりやすく解説します。 イテレータとは イテレータ（Iterator）は、値の列を生成する値で、要素を順番に取り出すことができる仕組みです。Rust で [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">イテレータ（Iterator）</span>の基本を初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">イテレータとは</h2>



<p><span class="jinr-d--text-color d--marker1 d--bold">イテレータ（Iterator）</span>は、値の列を生成する値で、要素を順番に取り出すことができる仕組みです。Rust では、文字列や <code>Vec</code> などから要素を取り出して処理するイテレータが用意されています。他にも、様々な場面でイテレータの仕組みが利用されています。</p>



<p>Rust の <code>for</code> 文はイテレータにとって自然に扱える構文となっており、シンプルなプログラム例は以下のようなものです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let v = vec![1, 2, 3];

    for x in v {
        println!("{}", x);
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
1
2
3</pre>



<p>Rust では、このような繰り返し処理の多くがイテレータを使って実装されており、Rust における重要な仕組みです。Rust のイテレータは、具体的には、<code>Iterator</code> トレイトや <code>IntoIterator</code> トレイトにより表現されています。</p>



<p>この記事では、<span class="jinr-d--text-color d--marker1 d--bold">Rust のイテレータ（Iterator）の基本</span>を解説します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>この記事では、トレイトに関する基本知識が必要です。トレイトについては「<a href="https://rust-tech.nkhn37.net/rust-trait-basic/" target="_blank" rel="noreferrer noopener">トレイトの基本を分かりやすく解説</a>」を参考にしてください。</p>
</div>
		</div></section>



<div id="nkhn3-720190527" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">イテレータの基本</h2>



<p>イテレータを実現する中心的なトレイトは、<span class="jinr-d--text-color d--marker1 d--bold"><code>Iterator</code></span> トレイトと <span class="jinr-d--text-color d--marker1 d--bold"><code>IntoIterator</code></span> トレイトです。ここでは、それぞれの概要について紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>Iterator</code> トレイト</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>Iterator</code></span> トレイトは、以下のように定義されています。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pub trait Iterator {
    type Item;

    // Required method
    fn next(&amp;mut self) -> Option&lt;Self::Item>;

    ...(他のメソッドは省略)...
}</pre>



<p><code>Item</code> という取り出す要素の型と <code>next</code> メソッドを持ちます。独自の型に <code>Iterator</code> トレイトを実装する際には <code>next</code> メソッドは必須のメソッドになります。他にもトレイトで定義されているメソッドはありますが、明確に定義しない場合はデフォルト実装が使用されます。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>Iterator</code> トレイトの詳細については、公式ドキュメントの<a href="https://doc.rust-lang.org/std/iter/trait.Iterator.html" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。</p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold"><code>next</code> メソッド</h4>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>next</code></span> メソッドは、イテレータの中心となる重要なメソッドです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let v = vec![1, 2, 3];
    let mut iter = v.iter();

    println!("{:?}", iter.next()); // Some(1)
    println!("{:?}", iter.next()); // Some(2)
    println!("{:?}", iter.next()); // Some(3)
    println!("{:?}", iter.next()); // None
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Some(1)
Some(2)
Some(3)
None</pre>



<p><code>iter</code> メソッドは、対象のイテレータを取得します。（<code>iter</code> については後ほど説明します。）</p>



<p>イテレータにおける <code>next</code> メソッドは、順に要素を取り出し、値 <code>x</code> がある場合は、<code>Option</code> 型の <code>Some(x)</code> を返却します。要素を取り出し続け、取り出す要素がなくなったら最後に <code>None</code> を返却します。 イテレータは、<code>Option</code> 型を使って処理の終了を表現していることがポイントです。</p>



<p><code>v</code> は、イミュータブル（変更不可）ですが、<code>iter</code> は <code>mut</code> を付けてミュータブル（変更可能）にしています。これは、<code>next()</code> メソッドがイテレータ自身の状態を更新するためであり、イテレータは <code>mut</code> で宣言する必要があります。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>IntoIterator</code> トレイト</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>IntoIterator</code></span> トレイトは、イテレータを生成できる型を表すトレイトで、以下のように定義されています。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pub trait IntoIterator {
    type Item;
    type IntoIter: Iterator&lt;Item = Self::Item>;

    // Required method
    fn into_iter(self) -> Self::IntoIter;
}</pre>



<p><code>IntoIterator</code> を実装している型は、<code>into_iter</code> メソッドによってイテレータに変換することができます。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>IntoIterator</code> トレイトの詳細については、公式ドキュメントの<a href="https://doc.rust-lang.org/std/iter/trait.IntoIterator.html" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。</p>
</div>
		</div></section>



<h4 class="wp-block-heading jinr-heading d--bold"><code>into_iter</code> メソッド</h4>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>into_iter</code></span> メソッドは、値や参照からイテレータを生成するメソッドです。<code>into_iter()</code> で理解しておくべきことは以下の通りです。対象 <code>v</code> に対してそれぞれ呼ばれる実装が変わります。</p>



<ul class="wp-block-list jinr-list">
<li><code>(&amp;v).into_iter()</code>：不変参照のイテレータを生成する</li>



<li><code>(&amp;mut v).into_iter()</code>：可変参照のイテレータを生成する</li>



<li><code>v.into_iter()</code>：所有権を移動するイテレータを生成する</li>
</ul>



<p>以下の例を見てみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let v1 = vec![1, 2, 3];

    // 不変参照のイテレータを作成
    for x in (&amp;v1).into_iter() {
        println!("{}", x);
    }

    let mut v2 = vec![4, 5, 6];

    // 可変参照のイテレータを作成
    for x in (&amp;mut v2).into_iter() {
        *x += 1; // 各要素に1を加える
        println!("{}", x);
    }

    let v3 = vec![7, 8, 9];

    // 所有権を移動するイテレータを作成
    for x in v3.into_iter() {
        println!("{}", x);
    }

    // v3は所有権が移動したため、ここで使用できない
    // println!("{:?}", v3); // コンパイルエラー
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
1
2
3
5
6
7
7
8
9</pre>



<p>このように、<code>into_iter()</code> は同じ名前のメソッドであっても、値に対して呼ぶのか、参照に対して呼ぶのかで返すイテレータの型が異なります。この違いは、<code>IntoIterator</code> が「値」「不変参照」「可変参照」のそれぞれに対して実装されていることによるものです。そのため、要素の型も <code>T</code> / <code>&amp;T</code> / <code>&amp;mut T</code> のように変化します。なお、<code>T</code> は型パラメータです。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>for</code> 文と <code>Iterator</code> の関係</h3>



<p>Rust の <code>for</code> 文は、<span class="jinr-d--text-color d--marker1 d--bold"><code>IntoIterator</code> トレイトを実装している型</span>に対して使用できます。つまり、<code>for</code> 文は内部的に <code>into_iter()</code> を呼び出し、イテレータとして要素を取り出しています。</p>



<p><code>for</code> 文で繰り返し処理を実装する場合は、明示的に <code>into_iter()</code> を書かなくても、以下のように不変参照で繰り返し処理を行うことができます。なお、可変参照や所有権移動の場合も同様に考えることができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">for x in &amp;v {
    println!("{}", x);
}</pre>



<p>これは、内部的には、概ね次のような処理が行われていると考えることができます。<br></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let v = vec![1, 2, 3];

    let mut iter = (&amp;v).into_iter();

    while let Some(x) = iter.next() {
        println!("{}", x);
    }
}</pre>



<p>つまり、「<code>for x in &amp;v</code>」は、<code>(&amp;v).into_iter()</code> を使ってイテレータを生成し、<code>next()</code> で要素を順番に取り出して処理をしているというイメージです。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox1 ">
			<i class="jif jin-ifont-v2bulb" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>ここで示したコードは概念的な説明であり、Rust の内部実装が必ずしもこの通りであることを示すものではない点に注意してください。</p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>for</code> 文の基本については「<a href="https://rust-tech.nkhn37.net/rust-for-while-loop-basic/" target="_blank" rel="noreferrer noopener">繰り返し処理（for, while, loop）を分かりやすく解説</a>」を参考にしてください。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">コレクションにおける <code>iter</code> や <code>iter_mut</code> メソッド</h3>



<p><code>Vec</code> などのコレクションでは、<code>Iterator</code> を返すメソッドとして、<span class="jinr-d--text-color d--marker1 d--bold"><code>iter</code></span> メソッドや <span class="jinr-d--text-color d--marker1 d--bold"><code>iter_mut</code></span> メソッドが提供されています。名称の通り、<code>iter</code> メソッドは不変参照のイテレータを、<code>iter_mut</code> メソッドは、可変参照のイテレータを返却します。</p>



<p>以下の例で見てみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    let mut v = vec![1, 2, 3];

    // iter メソッドで不変参照のイテレータを返却
    for x in v.iter() {
        println!("{}", x);

        // 不変参照なので、以下のように値を変更することはできない
        // *x += 1;
    }

    // iter_mut メソッドで可変参照のイテレータを返却
    for x in v.iter_mut() {
        *x += 1;
        println!("{}", x);
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
1
2
3
2
3
4</pre>



<p>例えば、<code>iter</code> を使用すると要素への不変参照を順番に取り出すことができます。不変参照なので、値を変更しようとするとコンパイルエラーとなります。一方で、<code>iter_mut</code> を使用すると要素への可変参照を取得できるため、要素の値を書き換えることができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ポイント</h4>



<p>多くのコレクションでは以下のような対応関係があります。</p>



<ul class="wp-block-list jinr-list">
<li><code>v.iter()</code> は <code>(&amp;v).into_iter()</code> に対応</li>



<li><code>v.iter_mut()</code> は <code>(&amp;mut v).into_iter()</code> に対応</li>
</ul>



<p>つまり、<code>iter</code> や <code>iter_mut</code> は、参照に対する <code>into_iter()</code> をより分かりやすく使うためのメソッドと考えることができます。ただし、誤解しやすいポイントですが、<code>iter</code> や <code>iter_mut</code> は、<code>Iterator</code> トレイトや <code>IntoIterator</code> トレイトで定義されているメソッドではありません。</p>



<p>これらは、Rust の標準ライブラリにおいて、コレクションがイテレータを生成するための便利なメソッドとして提供しているものです。そのため、必ずしも上記対応が保証されているわけではありませんので注意してください。</p>



<p><code>Iterator</code> トレイトの必須メソッドとされている <code>next</code> や <code>IntoIterator</code> トレイトの必須メソッドとされている <code>into_iter</code> とは位置づけが異なることを理解しておきましょう。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">イテレータ（Iterator）</span>の基本を解説しました。</p>



<p>イテレータは、値の列を生成する値で、要素を順番に取り出すことができる仕組みで <code>for</code> 文などの繰り返し処理で利用されます。</p>



<p>イテレータの中心となるのが、<code>Iterator</code> トレイトと <code>IntoIterator</code> トレイトです。この記事では、それぞれの必須メソッドである <code>next</code> や <code>into_iter</code> メソッドの役割について説明しました。また、<code>for</code> 文との関係や、Rust のコレクションで提供される <code>iter</code>、<code>iter_mut</code> といったメソッドについても紹介しました。</p>



<p>イテレータは、Rust のデータ処理の中心的な仕組みです。基本の考え方をしっかりと理解しておきましょう。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては&nbsp;<a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/iterator-basic" target="_blank" rel="noreferrer noopener">GitHub</a>&nbsp;にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section><div id="nkhn3-4279651638" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-iterator-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】クロージャの型とトレイト（Fn / FnMut / FnOnce）</title>
		<link>https://rust-tech.nkhn37.net/rust-closure-fn-traits/</link>
					<comments>https://rust-tech.nkhn37.net/rust-closure-fn-traits/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 06 Mar 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[Fn]]></category>
		<category><![CDATA[FnMut]]></category>
		<category><![CDATA[FnOnce]]></category>
		<category><![CDATA[キャプチャ]]></category>
		<category><![CDATA[クロージャ]]></category>
		<category><![CDATA[トレイト]]></category>
		<category><![CDATA[所有権]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1843</guid>

					<description><![CDATA[Rust におけるクロージャ（Closure）の型とトレイト（Fn / FnMut / FnOnce）について初心者にも分かりやすく解説します。 Rust のクロージャの型とトレイト Rust におけるクロージャ（Clo [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クロージャ（Closure）の型とトレイト（Fn / FnMut / FnOnce）</span>について初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">Rust のクロージャの型とトレイト</h2>



<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クロージャ（Closure）</span>とは、「<strong>その場で定義できる無名の関数</strong>のようなもの」のことです。クロージャの使い方の基本については「<a href="https://rust-tech.nkhn37.net/rust-closure-basic/" target="_blank" rel="noreferrer noopener">クロージャの基本と使い方を分かりやすく解説</a>」を参考にしてください。</p>



<p>この記事では、基本からは一段深く、<span class="jinr-d--text-color d--marker1 d--bold">クロージャの「型」と「トレイト」</span>について踏み込んで紹介します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>以降の内容の理解には型やトレイトの基本的な知識が必要です。基本的な内容については、以下を参考にしてください。</p>



<ul class="wp-block-list jinr-list">
<li><a href="https://rust-tech.nkhn37.net/rust-basic-types/" target="_blank" rel="noreferrer noopener">基本型を分かりやすく解説（スカラー型と複合型）</a></li>



<li><a href="https://rust-tech.nkhn37.net/rust-structs-basic/" target="_blank" rel="noreferrer noopener">構造体の使い方を分かりやすく解説</a></li>



<li><a href="https://rust-tech.nkhn37.net/rust-trait-basic/" target="_blank" rel="noreferrer noopener">トレイトの基本を分かりやすく解説</a></li>
</ul>
</div>
		</div></section>



<div id="nkhn3-3576384809" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">クロージャの型</h2>



<p>まずは、クロージャーの本質について確認してみましょう。結論から述べると<span class="jinr-d--text-color d--marker1 d--bold">クロージャは、コンパイラが生成する固有の型</span>です。</p>



<p>記事冒頭で「その場で定義できる無名の関数<span class="jinr-d--text-color d--marker1 d--bold">のようなもの</span>」と説明しましたが、実際には「関数」ではありません。ここではその違いを具体的なコードで確認します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">関数の型とクロージャの型は異なる</h3>



<p>Rust のクロージャは、以下のように使用することができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // クロージャで使用する外部変数
    let base = 1;

    // クロージャーを定義
    let add_one_closure = |x| x + base;
    println!("クロージャーを呼び出す: {}", add_one_closure(5));
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
クロージャーを呼び出す: 6</pre>



<p>この例では、<code>base</code> という外部変数をキャプチャしています。これにより <code>add_one_closure</code> は引数 <code>x</code> に与えられた値に <code>base</code> の値を加算する機能を提供します。</p>



<p>では、このクロージャが関数として扱えるかを試してみましょう。以下の <code>call_function</code> は関数を引数として受け取り呼び出すだけの関数です。比較のために <code>add_one</code> という通常の関数を用意しています。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 関数を引数として受け取り、呼び出す関数
fn call_function(f: fn(i32) -> i32, x: i32) -> i32 {
    f(x)
}

// 1を加算する通常の関数
fn add_one(x: i32) -> i32 {
    x + 1
}

fn main() {
    // クロージャで使用する外部変数
    let base = 1;

    // クロージャーを定義
    let add_one_closure = |x| x + base;
    println!("クロージャーを呼び出す: {}", add_one_closure(5));

    // 通常の関数を呼び出す
    println!(
        "通常の関数を call_function 経由で呼び出す: {}",
        call_function(add_one, 5)
    );

    // クロージャーを call_function に渡す。（これはエラーとなる）
    // println!(
    //     "クロージャーを call_function 経由で呼び出す: {}",
    //     call_function(add_one_closure, 5)
    // );
}</pre>



<p>例の <code>call_function</code> は、「<code>fn(i32) -&gt; i32</code>」という型を受け取ります。この型は、<span class="jinr-d--text-color d--marker1 d--bold">関数ポインタ型</span>と呼ばれ、「<code>i32</code> 型を受け取り <code>i32</code> 型の結果を返す」ことを意味しています。</p>



<p>通常関数の <code>add_one</code> も、クロージャである <code>add_one_closure</code> も「<code>i32</code> 型を受け取り <code>i32</code> 型の結果を返す」という形式に一致しています。しかし、例でコメントアウトしているクロージャー <code>add_one_closure</code> を <code>call_function</code> に渡している部分はコンパイルエラーとなります。</p>



<p>理由はシンプルで、クロージャーの型は「<code>fn(i32) -&gt; i32</code>」ではないためです。この結果から分かりますが、<span class="jinr-d--text-color d--marker1 d--bold">クロージャは、コンパイラが生成する固有の型</span>となっています。</p>



<h3 class="wp-block-heading jinr-heading d--bold">トレイト境界でクロージャと関数を同様に扱う</h3>



<p>上記で、通常関数とクロージャは型が異なることが分かりました。しかし、関数にクロージャを渡して実行したいケースは非常に多くあります。関数とクロージャーを同じように扱う方法はないのでしょうか？もちろんあります。ポイントとなるのが <span class="jinr-d--text-color d--marker1 d--bold"><code>Fn</code> トレイト</span>です。</p>



<p>次の例のようにトレイト境界を用いた <code>call_function</code> を使用すれば、通常関数もクロージャも両方受け取ることができるようになります。<code>Fn</code> トレイトについては詳細は後述しますので、一旦ここでは、このようにすることで対応できると理解していただければと思います</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// クロージャも引数として受け取ることができる関数
fn call_function_closure&lt;F>(f: F, x: i32) -> i32
where
    F: Fn(i32) -> i32,
{
    f(x)
}

// 1を加算する通常の関数
fn add_one(x: i32) -> i32 {
    x + 1
}

fn main() {
    // クロージャで使用する外部変数
    let base = 1;

    // クロージャーを定義
    let add_one_closure = |x| x + base;
    println!("クロージャーを呼び出す: {}", add_one_closure(5));

    // 通常の関数を呼び出す
    println!(
        "通常の関数を call_function 経由で呼び出す: {}",
        call_function_closure(add_one, 5)
    );

    // クロージャーを call_function_closure に渡す
    println!(
        "クロージャーを call_function_closure 経由で呼び出す: {}",
        call_function_closure(add_one_closure, 5)
    );
}</pre>



<p>このようにすることで「通常の関数」と「クロージャ」をどちらも同じように扱うことができます。これは、通常の関数もクロージャも、<code>Fn</code> トレイトを通じて扱うことができるためです。</p>



<p>実は、クロージャは、常に同じトレイトを実装するわけではありません。外部変数のキャプチャ方法（不変参照、可変参照、所有権移動）によって実装されるトレイトが変わります。以降では、クロージャのトレイトについて説明していきます。</p>



<h2 class="wp-block-heading jinr-heading d--bold">クロージャのトレイト（<code>Fn</code> / <code>FnMut</code> / <code>FnOnce</code>）</h2>



<p>Rust では、この違いを表現するために、以下の 3 つのトレイトが用意されています。</p>



<ul class="wp-block-list jinr-list">
<li><span class="jinr-d--text-color d--marker1 d--bold"><code>Fn</code></span>：不変参照</li>



<li><span class="jinr-d--text-color d--marker1 d--bold"><code>FnMut</code></span>：可変参照</li>



<li><span class="jinr-d--text-color d--marker1 d--bold"><code>FnOnce</code></span>：所有権の移動</li>
</ul>



<p>これらは、<span class="jinr-d--text-color d--marker1 d--bold">クロージャが外部の変数をどのように扱うか</span>によって使い分けられます。以降では、クロージャのトレイトの違いについて詳しく見ていきます。</p>



<p>クロージャの基本記事「<a href="https://rust-tech.nkhn37.net/rust-closure-basic/" target="_blank" rel="noreferrer noopener">クロージャの基本と使い方を分かりやすく解説</a>」で紹介しているクロージャのキャプチャ方法は、この各トレイトに相当しています。基本記事で使用したコードを再掲しながら確認してみましょう。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>Fn</code> トレイト（不変参照）</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>Fn</code> トレイト</span>は、外部の変数を変更せずに利用するクロージャに対して実装されるトレイトです。つまり、キャプチャした変数を「読み取るだけ」の 場合に <code>Fn</code> が実装されます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 不変参照でのキャプチャ例
    let x = 10;
    // x は不変参照でキャプチャされる
    let f = |y| x + y;

    // クロージャの呼び出し
    println!("f(5) = {}", f(5));
    // xはまだ使用可能
    println!("x = {}", x);
}</pre>



<p>例では、<code>x</code> をクロージャの中で参照しているだけで変更していません。そのため、このクロージャは <code>Fn</code> トレイトを実装します。<code>Fn</code> のクロージャは、状態を変更しないため何度でも安全に呼び出すことができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>FnMut</code> トレイト（可変参照）</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>FnMut</code> トレイト</span>は、キャプチャした変数を「変更する」クロージャに対して実装されるトレイトです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 可変参照でのキャプチャ例
    let mut count = 0;
    println!("count before: {}", count);
    // countは可変参照でキャプチャされる
    let mut g = || count += 1;

    // クロージャを呼び出すとcountが変更される
    g();
    // countは変更されている
    println!("count after: {}", count);
}</pre>



<p>例では、クロージャの中で <code>count</code> を変更しています。そのため、このクロージャは <code>FnMut</code> トレイトを実装します。</p>



<p><code>FnMut</code> のクロージャは、キャプチャした変数を変更する可能性があります。そのため、呼び出し時には、クロージャ自身が変更される可能性があるため、クロージャを変数に束縛するには「<code>let mut g</code>」のように <code>mut</code> をつける必要があります。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>FnOnce</code> トレイト（所有権の移動）</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>FnOnce</code> トレイト</span>は、「キャプチャした値の所有権を消費する」クロージャに対して実装されるトレイトです。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== move による所有権の移動でのキャプチャ例
    let s = String::from("Hello");
    // s は move で所有権がクロージャに移動される
    let h = move || println!("{s} World!");

    // 実行時に s は消費されて使用できなくなる
    h();
    // sはmoveで所有権が移動されているため以降は使用できない
    // println!("{s}"); // コンパイルエラー
}</pre>



<p>例では、<code>move</code> を使用して <code>s</code> の所有権をクロージャに移動しています。このような場合、クロージャはキャプチャした値を消費する可能性があるため、1 回しか安全に呼び出すことができません。そのため、このようなクロージャは <code>FnOnce</code> トレイトを実装します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><strong>【<code>move</code> について】</strong></p>



<p>例では、明示的に <code>move</code> を付与して実装していますが、Rust はコンパイラがクロージャの使われ方で判断するため、<code>move</code> の指定がなくても <code>FnOnce</code> となる場合があります。代表的な例は、以下のようにクロージャの中で <code>drop()</code> を使用するような場合です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">let s = String::from("Hello");
let h = || drop(s);</pre>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold"><code>Fn</code> / <code>FnMut</code> / <code>FnOnce</code> の関係性</h3>



<p>上記で紹介したトレイトは、次のような関係になっています。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Fn ⊂ FnMut ⊂ FnOnce</pre>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="448" height="449" src="https://rust-tech.nkhn37.net/wp-content/uploads/2026/03/image.png" alt="Fn / FnMut / FnOnce の関係性" class="wp-image-1857" style="aspect-ratio:0.9978047578513507;width:256px;height:auto" srcset="https://rust-tech.nkhn37.net/wp-content/uploads/2026/03/image.png 448w, https://rust-tech.nkhn37.net/wp-content/uploads/2026/03/image-300x300.png 300w, https://rust-tech.nkhn37.net/wp-content/uploads/2026/03/image-150x150.png 150w, https://rust-tech.nkhn37.net/wp-content/uploads/2026/03/image-320x320.png 320w" sizes="(max-width: 448px) 100vw, 448px" /><figcaption class="wp-element-caption">Fn / FnMut / FnOnce の関係性</figcaption></figure>
</div>


<p>上記図は「<code>Fn</code> は <code>FnMut</code> のサブトレイト」「<code>FnMut</code> は <code>FnOnce</code> のサブトレイト」という意味を表しています。つまり、<code>Fn</code> を実装するクロージャは <code>FnMut</code> としても扱うことができ、<code>FnMut</code> を実装するクロージャは <code>FnOnce</code> としてもあつかえるという関係になっています。</p>



<p>記事の前半で <code>Fn</code> をトレイト境界に持つ関数の例を紹介しましたが、この <code>call_function</code> は、<code>FnMut</code> のクロージャを受け取ることができません。一方で、<code>FnMut</code> をトレイト境界に持つ関数は、<code>Fn</code> トレイトのクロージャを受け取ることが可能となります。</p>



<p>ここまでで紹介してきたように、Rust では、クロージャの振る舞いに応じて <code>Fn</code> / <code>FnMut</code> / <code>FnOnce</code> のトレイトが自動的に決定されます。このような仕組みとなっていることをしっかり理解していただければと思います。</p>



<div id="nkhn3-3945628747" class="nkhn3--2 nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クロージャ（Closure）の型とトレイト（<code>Fn</code> / <code>FnMut</code> / <code>FnOnce</code>）</span>について解説しました。</p>



<p>クロージャは、通常の関数とは異なり、コンパイラが生成する固有の型です。一方で、トレイト境界を使うことで通常の関数と同じように扱うことができます。</p>



<p>また、クロージャは、キャプチャする外部変数の扱い方に応じて、<code>Fn</code> / <code>FnMut</code> / <code>FnOnce</code> のいずれかのトレイトを実装します。これらの違いを理解しておくことで、クロージャを引数として受け取る関数や所有権が関わるコードをより正確に理解して実装ができるようになります。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては&nbsp;<a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/closure-traits" target="_blank" rel="noreferrer noopener">GitHub</a>&nbsp;にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section><div id="nkhn3-1567829143" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-closure-fn-traits/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】クロージャの基本と使い方を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-closure-basic/</link>
					<comments>https://rust-tech.nkhn37.net/rust-closure-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 20 Feb 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[move]]></category>
		<category><![CDATA[キャプチャ]]></category>
		<category><![CDATA[クロージャ]]></category>
		<category><![CDATA[借用]]></category>
		<category><![CDATA[型推論]]></category>
		<category><![CDATA[所有権]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1783</guid>

					<description><![CDATA[Rust におけるクロージャ（Closure）の基本を初心者にも分かりやすく解説します。 クロージャ（Closure）とは Rust におけるクロージャ（Closure）とは、「その場で定義できる無名の関数のようなもの」 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クロージャ（Closure）</span>の基本を初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">クロージャ（Closure）とは</h2>



<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クロージャ（Closure）</span>とは、「<strong>その場で定義できる無名の関数</strong>のようなもの」のことです。</p>



<p>通常の <code>fn</code> で定義する関数との大きな違いは、外部のスコープにある変数を利用できることです。この「外側の変数を取り込んで使う」ことを「<strong>キャプチャ（capture）</strong>」と呼びます。</p>



<p>共通的な変数をクロージャの中に取り込んでおくことで、他の可変な値と組み合わせながら、柔軟で再利用可能な処理を定義することができます。</p>



<p>この記事では、<span class="jinr-d--text-color d--marker1 d--bold">Rust におけるクロージャの基本的な使い方や考え方</span>について紹介します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><strong>【無名関数とクロージャ】</strong></p>



<p>厳密には、クロージャという言葉は「<strong>外部の変数をキャプチャした関数</strong>」のことを言います。しかし、Rust では、外部の変数をキャプチャしていない場合でも、すべてクロージャと呼びます。</p>



<p>Python などの他の言語では、「無名関数」と「クロージャ」を分けて説明されることがあります。一方で、Rust コミュニティでは「無名関数」という用語はほとんど使われず、一貫してクロージャという言葉で説明がされる点を覚えておくとよいでしょう。</p>
</div>
		</div></section>



<div id="nkhn3-2187652157" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">クロージャの基本<br></h2>



<h3 class="wp-block-heading jinr-heading d--bold">クロージャの基本的な使い方</h3>



<p>基本的なクロージャの使い方を紹介します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">|引数1, 引数2, ...| 式</pre>



<p>クロージャの構文は非常にシンプルです。上記のように <code>||</code> 内に引数を列挙し、クロージャの返却値となる式をその後に記載します。引数なしのクロージャー (<code>|| 式</code>) でも問題ありません。</p>



<p>また、複数の文を書く場合は、以下のように <code>{}</code> のブロックを使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">|引数1, 引数2, ...| {
    文;
    ...;
    式
}</pre>



<p>最後の式は、クロージャの戻り値になります。最後に <code>;</code> (セミコロン) をつけると戻り値は <code>()</code> となります。</p>



<p>それでは、簡単な具体例で確認してみましょう。</p>



<h4 class="wp-block-heading jinr-heading d--bold">単一式の例</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 単一の式のクロージャ例
    let add = |a, b| a + b;
    println!("add(2, 3) = {}", add(2, 3));
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
add(2, 3) = 5</pre>



<p>この例では、変数 <code>a</code> と <code>b</code> を受け取り <code>a + b</code> という単一の式を計算するクロージャを定義して <code>add</code> という変数名に束縛しています。<code>a + b</code> がクロージャの戻り値になります。</p>



<p>クロージャを使用する時には「<code>add(2, 3)</code>」のように使用します。もちろん、<code>add(4, 5)</code>、 &#8230;のように任意の引数での再利用が可能です。</p>



<p>単一の式の場合であれば、<code>{}</code> を使用しなくても上記のように簡潔に書くことができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">引数なしの例</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 引数なしのクロージャ例
    let greet = || "Hello, Rust!";
    println!("greet() = {}", greet());
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
greet() = Hello, Rust!</pre>



<p>クロージャは、引数がなくても使用できます。引数がない場合、|| のように何も書かずに定義します。この例では、<code>"Hello, Rust!"</code> という文字列リテラルがそのまま戻り値になります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ブロック形式の例</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== ブロック形式のクロージャ例
    let multiply = |a, b| {
        println!("calculating {a} * {b} ...");
        // 最後の式がクロージャの戻り値になる
        a * b
    };
    println!("multiply(3, 5) = {}", multiply(3, 5));
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
calculating 3 * 5 ...
multiply(3, 5) = 15</pre>



<p>複数の文を実行したい場合には、<code>{}</code> ブロックを使用します。例では、計算前に <code>println!</code> でメッセージを表示し、その後に <code>a * b</code> を評価しています。</p>



<p>Rust では、ブロックの最後の式が戻り値になるというルールがあります。そのため、<code>a * b</code> に <code>;</code> (セミコロン) をつけないことが重要です。<code>;</code> を付けた場合の返却値は <code>()</code> となります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">外側の変数をキャプチャする例</h4>



<p>ここまでの例は、関数とほぼ同じような使い方でした。しかし、クロージャの本質は「外側の変数を利用できること」です。以下の例で、外側の変数をキャプチャする例を見てみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 外側の変数をキャプチャするクロージャ例
    let base = 10;

    let add_to_base = |x| base + x;
    println!("add_to_base(5) = {}", add_to_base(5));
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
add_to_base(5) = 15</pre>



<p>この例では、<code>base</code> という変数をクロージャの外側で定義しています。<code>add_to_base</code> は、引数 <code>x</code> だけを受け取っていますが、計算で <code>base</code> も利用しています。このように <code>add_to_base</code> を用意しておくと、様々な <code>x</code> に対して <code>base</code> を足した結果を再利用して計算できます。</p>



<p>あたかも add_to_base が base 変数を捕捉した状態で使いまわせるため「キャプチャする」という表現が使われています。</p>



<p>このように、外側のスコープにある変数を取り込んで使用することができるのがクロージャの本質です。ここまでの例を振り返るとクロージャーは次のような特徴があることが分かります。</p>



<ul class="wp-block-list jinr-list">
<li>関数のように振る舞う</li>



<li><code>fn</code> を使わなくても、その場で定義することができる</li>



<li>外側の変数を利用することができる（キャプチャできる）</li>
</ul>



<p>つまり、単なる無名関数というだけではなく、定義された環境設定ごと関数を扱える仕組みであることがクロージャの本当の価値です。</p>



<h3 class="wp-block-heading jinr-heading d--bold">クロージャの型注釈と型推論</h3>



<h4 class="wp-block-heading jinr-heading d--bold">引数の型注釈</h4>



<p>クロージャーは型推論がされるため、基本的には型注釈を入れる必要はありません。以下のように型注釈を入れたクロージャも使うことができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 単一の式のクロージャ例 (型注釈あり)
    let subtract = |a: i32, b: i32| a - b;
    println!("subtract(5, 2) = {}", subtract(5, 2));
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
subtract(5, 2) = 3</pre>



<p>例のように <code>a: i32, b: i32</code> といった形で型注釈を書くことができます。なお、戻り値については、<code>let subtract = |a: i32, b: i32| -&gt; i32 { a - b };</code> のように書くことも可能ですが、引数の型が決まれば、戻り値の型は式から自動推論できるため、通常は記載しません。</p>



<h4 class="wp-block-heading jinr-heading d--bold">クロージャの型推論</h4>



<p>クロージャは型推論をすると記載しましたが、どこで型が確定するかというと「<span class="jinr-d--text-color d--marker1 d--bold">最初にクロージャが使用されたときの型</span>」で確定となります。そのため、先ほどの例で一度 <code>add(2, 3)</code> と使用した<span class="jinr-d--text-color d--marker1">後に</span>以下のように、<code>floating-point</code> で使用しようとするとコンパイルエラーとなります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">println!("add(1.0, 2.0) = {}", add(1.0, 2.0));</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【エラー例】
error[E0308]: arguments to this function are incorrect
  --> rust-basic\closure-basic\examples\closure_basic.rs:28:36
   |
28 |     println!("add(1.0, 2.0) = {}", add(1.0, 2.0));
   |                                    ^^^ ---  --- expected integer, found floating-point number
   |                                        |
   |                                        expected integer, found floating-point number</pre>



<h2 class="wp-block-heading jinr-heading d--bold">クロージャのキャプチャの方法</h2>



<p>ここでは、クロージャのキャプチャについて少し詳しく見てみましょう。キャプチャとは、クロージャが外側のスコープにある変数を取り込んで利用することでした。</p>



<p>Rust のクロージャでは、外側の変数をどのように扱うかに応じて、キャプチャ方法をコンパイラが自動で選択します。主なキャプチャの方法には以下の 3 種類です。</p>



<ol class="wp-block-list jinr-list">
<li>不変参照でのキャプチャ</li>



<li>可変参照でのキャプチャ</li>



<li><code>move</code> による所有権の移動でのキャプチャ</li>
</ol>



<h3 class="wp-block-heading jinr-heading d--bold">不変参照でのキャプチャ</h3>



<p>外側の変数を「読み取るだけ」であればクロージャは、変数を不変参照でキャプチャします。この場合、外側の変数は所有権を失わないため、クロージャ呼び出し後も引き続き利用できます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 不変参照でのキャプチャ例
    let x = 10;
    // x は不変参照でキャプチャされる
    let f = |y| x + y;

    // クロージャの呼び出し
    println!("f(5) = {}", f(5));
    // xはまだ使用可能
    println!("x = {}", x);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
f(5) = 15
x = 10</pre>



<p>例のクロージャでは、<code>x</code> を不変参照しているだけで変更していません。そのため、クロージャを呼び出した後でも <code>x</code> は使用できます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">可変参照でのキャプチャ</h3>



<p>クロージャの中で外側の変数を変更する場合、クロージャはその変数を可変参照でキャプチャします。以下は、<code>count</code> 変数をクロージャ内部でカウントアップしているような例です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== 可変参照でのキャプチャ例
    let mut count = 0;
    println!("count before: {}", count);
    // countは可変参照でキャプチャされる
    let mut g = || count += 1;

    // クロージャを呼び出すとcountが変更される
    g();
    // countは変更されている
    println!("count after: {}", count);
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
count before: 0
count after: 1</pre>



<p>可変参照でキャプチャする場合は、外側の変数は <code>let mut</code> により、変更可能（ミュータブル）な変数として定義する必要があります。また、クロージャを変数（上記例では <code>g</code>）に束縛する場合は、<code>g</code> についても <code>let mut</code> で変更可能な形で定義する必要があります。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>move</code> による所有権の移動でのキャプチャ</h3>



<p>これまでの例では、外側の変数は参照としてキャプチャされていました。以下のようにクロージャの定義の前に <span class="jinr-d--text-color d--marker1 d--bold"><code>move</code></span> をつけることで、外側の変数は所有権ごとクロージャに移動します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fn main() {
    // ===== move による所有権の移動でのキャプチャ例
    let s = String::from("Hello");
    // s は move で所有権がクロージャに移動される
    let h = move || println!("{s} World!");

    // 実行時に s は消費されて使用できなくなる
    h();
    // sはmoveで所有権が移動されているため以降は使用できない
    // println!("{s}"); // コンパイルエラー
}
</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Hello World!</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【move 後のコメントアウト部分を外した場合のコンパイルエラー 一部抜粋】
error[E0382]: borrow of moved value: `s`
  --> rust-basic\closure-basic\examples\closure_capture.rs:31:16
   |
24 |     let s = String::from("Hello");
   |         - move occurs because `s` has type `String`, which does not implement the `Copy` trait
25 |     // s は move で所有権がクロージャに移動される
26 |     let h = move || println!("{s} World!");
   |             -------            - variable moved due to use in closure
   |             |
   |             value moved into closure here
...
31 |     println!("{s}"); // コンパイルエラー
   |                ^ value borrowed here after move</pre>



<p>例のように、<code>move</code> を付けた時点で変数 <code>s</code> の所有権はクロージャに移動します。そのため、以降外側のスコープでは <code>s</code> は使用できません。使用しようとするとコンパイルエラーとなります。（例でコメントアウトしている部分を外して試してみてください。）</p>



<p><code>move</code> は、外側の値の所有権をクロージャ側に移して、クロージャがその値を保持できるようにしたい場合に使います。（例：スレッドに渡す、関数の外へ変数を持ち出す など）</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>所有権の基本については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-ownership-borrowing-basic/" target="_blank" rel="noreferrer noopener">所有権と借用の基本を分かりやすく解説</a></p>
</div>
		</div></section>



<div id="nkhn3-2794998222" class="nkhn3--2 nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">クロージャの型とトレイト</h2>



<p>クロージャの基本的な使い方を紹介してきました。記事の冒頭で、クロージャは「その場で定義できる無名の関数<span class="jinr-d--text-color d--marker1 d--bold">のようなもの</span>」という少し曖昧な表現をしました。これは、クロージャの型やトレイトをより理解すると、関数とは異なるということが分かるためです。</p>



<p>少し詳細な内容になるため、クロージャの型とトレイトについては「<a href="https://rust-tech.nkhn37.net/rust-closure-fn-traits/" target="_blank" rel="noreferrer noopener">クロージャの型とトレイト（Fn / FnMut / FnOnce）</a>」でまとめていますので参考にしてください。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クロージャ（Closure）</span>の基本を解説しました。</p>



<p>クロージャは 「 <code>|引数1, 引数2, …| 式</code>」の形式で、その場で定義できる無名の関数のような仕組みです。ブロック形式の場合は、最後の式が戻り値になります。また、型注釈は必要に応じて記載できますが、多くの場合は型推論に任せることができます。</p>



<p>さらに、クロージャの本質である「キャプチャ」について、不変参照・可変参照・<code>move</code> による所有権移動の 3 パターンを紹介しました。特に <code>move</code> を使うと、外側の値の所有権がクロージャに移動し、以降は外側のスコープでは利用できなくなる点が重要です。</p>



<p>クロージャは、その場で処理を定義できる非常に便利な機能で、Rust ではさまざまな場面で利用されます。まずは、基本的な書き方とキャプチャの考え方をしっかり押さえておきましょう。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/closure-basic" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section><div id="nkhn3-2803607461" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-closure-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust】anyhow で複数のエラーをまとめて扱う方法</title>
		<link>https://rust-tech.nkhn37.net/rust-anyhow-basic/</link>
					<comments>https://rust-tech.nkhn37.net/rust-anyhow-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 06 Feb 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[anyhow]]></category>
		<category><![CDATA[? 演算子]]></category>
		<category><![CDATA[bail!]]></category>
		<category><![CDATA[context]]></category>
		<category><![CDATA[thiserror]]></category>
		<category><![CDATA[エラー処理]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1697</guid>

					<description><![CDATA[Rust で anyhow を用いて複数のエラーをまとめて扱う方法について、初心者にも分かりやすく解説します。 anyhow クレートの概要 anyhow とは Rust のエラー処理では、Result&#60;T, E&#038; [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust で <span class="jinr-d--text-color d--marker1 d--bold"><code>anyhow</code> を用いて複数のエラーをまとめて扱う方法</span>について、初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold"><code>anyhow</code> クレートの概要</h2>



<h3 class="wp-block-heading jinr-heading d--bold"><code>anyhow</code> とは</h3>



<p>Rust のエラー処理では、<code>Result&lt;T, E&gt;</code> 型を使用して「成功（<code>Ok</code>）」か「失敗（<code>Err</code>）」かを表現するのが基本となります。この時、<code>E</code> は、エラーを表す型の型パラメータです。</p>



<p>エラーの型は、各種外部のクレートなど様々な機能でも個別に用意されており、扱うエラー型は多岐に渡るため、すべてのエラー型を意識して厳密にエラーに対する処理を実装していくことは、多くの負担がかかってしまいます。</p>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>anyhow</code></span> は、こうした「<span class="jinr-d--text-color d--marker1 d--bold">複数のエラーをまとめて扱いたい</span>」場面で非常に便利なクレートです。<code>anyhow::Error</code> という汎用的なエラー型を用いることで、アプリケーション側のエラー処理を簡潔に表現して扱うことができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>anyhow</code> の特徴（複数のエラーをまとめて扱う）</h3>



<p><code>anyhow</code> を使用する<span class="jinr-d--text-color d--marker1 d--bold">最大のメリットは、エラー型を 1 つに統一できること</span>です。</p>



<p>通常、Rust の <code>?</code> 演算子は、エラーが一致 または 変換できる場合（<code>From</code> トレイトによる変換が可能な場合）にしか使用することができません。そのため、複数のエラー型が混ざる処理では、エラー変換を自前で実装したり、独自エラー型にまとめる必要性が出てきます。</p>



<p><code>anyhow</code> を使用すると以下のような書き方ができるようになります。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ul class="wp-block-list jinr-list">
<li>関数の戻り値を <code>anyhow::Result&lt;T&gt;</code> ※にする。</li>



<li>エラー型の種類を意識せずに <code>?</code> で上位の呼び出し元に伝播することができる。</li>
</ul>
</div></div></section>



<p>なお、<code>anyhow</code> はエラーを握りつぶすためのものではありません。後ほど説明するようにエラーに追加の文脈情報（コンテキスト）を付与することで、原因調査をしやすくするための仕組みも提供します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><strong>【※ <code>anyhow::Result&lt;T&gt;</code> について】</strong></p>



<p><code>anyhow::Result&lt;T&gt;</code> は、<code>Result&lt;T, anyhow::Error&gt;</code> の型エイリアスです。<code>anyhow::Error</code> を毎回書く必要がなく、<code>use</code> で <code>anyhow::Result</code> をスコープに取り込めば、以下のように非常に簡潔に記載ができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use anyhow::Result;

fn run() -> Result&lt;()> {
    Ok()
}</pre>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold"><code>anyhow</code> の位置づけ（<code>Result&lt;T, E&gt;</code> や <code>thiserror</code> との関係性）</h3>



<p>Rust のエラー処理では、基本的に <code>Result&lt;T, E&gt;</code> 型を利用してエラーを処理します。この <code>E</code> は、エラーのためのジェネリックな型パラメータで、任意の型を使用することができます。</p>



<p><code>anyhow</code> を使用するということは、<code>E</code> に <code>anyhow::Error</code> を採用する設計を意味します。とにかくエラー型を統一して扱いたい場合には、<code>anyhow</code> は非常に向いています。</p>



<p>一方で、<code>thiserror</code> という独自エラー型を設計するクレートも非常によく使用されます。これは、自身で <code>MyError</code> 型を定義し、<code>Result&lt;T, MyError&gt;</code> のようにエラーの種類を明確に表現したい場合に向いています。クレートの位置づけを整理すると以下の通りです。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ul class="wp-block-list jinr-list">
<li><code>thiserror</code>：独自のエラー型を簡単に定義する。</li>



<li><code>anyhow</code>：様々なエラー型をまとめて取り扱うことができる。</li>
</ul>
</div></div></section>



<p>一般的には、ライブラリ側では&nbsp;<code>thiserror</code>、アプリケーション側では&nbsp;<code>anyhow</code>&nbsp;が使われることが多いです。ライブラリが用意している独自エラー型を、アプリケーション側が受け取った際には <code>anyhow::Error</code> に変換・統一して扱うという構成です。もちろん、独自エラーの情報を消してしまうわけではなく、元の独自エラーの情報を保持しつつ、<code>anyhow::Error</code> に統一します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>エラー処理の基本や <code>thiserror</code> については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-error-handling-basic/" target="_blank" rel="noreferrer noopener">エラー処理の基本を分かりやすく解説</a></p>



<p><a href="https://rust-tech.nkhn37.net/rust-thiserror-error-types/" target="_blank" rel="noreferrer noopener">thiserrorにより独自のエラー型を実装する方法</a></p>
</div>
		</div></section>



<div id="nkhn3-88203096" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold"><code>anyhow</code> の基本</h2>



<h3 class="wp-block-heading jinr-heading d--bold"><code>anyhow</code> の導入方法</h3>



<p><code>anyhow</code> は、他クレートと同様に <code>cargo add</code> または <code>Cargo.toml</code> に追記することで利用できるようになります。</p>



<p><strong>【<code>cargo add</code> で追加する場合】</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo add anyhow</pre>



<p><strong>【<code>Cargo.toml</code> に追記する場合】</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[dependencies]
anyhow = "1.0.101"</pre>



<p>例での記載バージョンは、記事執筆・更新時点での最新バージョンで記載しているため、導入時には crates.io の <a href="https://crates.io/crates/anyhow" target="_blank" rel="noreferrer noopener"><code>anyhow</code> のページ</a>を確認して指定してください。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>クレートや依存関係の基本については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-crates-basics/" target="_blank" rel="noreferrer noopener">クレート（バイナリ／ライブラリ）と依存関係の管理を分かりやすく解説</a></p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold"><code>?</code> で複数のエラーをまとめて扱う基本的な使い方</h3>



<p><code>anyhow</code> を利用する最も大きなメリットの 1 つは、ライブラリなどの複数のエラーをまとめて扱うことができることです。代表的な使い方として <code>?</code> 演算子により、<code>From</code> トレイトによる変換を通じて、外部エラーを <code>anyhow::Error</code> に変換して扱う方法を紹介します。</p>



<p>以下は、<code>input_file.txt</code> を読み込む際に、ファイルが存在しない場面と思ってください。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use anyhow::Result;
use std::fs;

fn main() -> Result&lt;()> {
    let path = "input_file.txt";

    // エラーを anyhow::Error に変換して返す
    let content = fs::read_to_string(path)?;

    println!("{content}");

    Ok(())
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Error: 指定されたファイルが見つかりません。 (os error 2)
error: process didn't exit successfully: `D:\RustProject\rust-tech-sample-source\target\debug\examples\anyhow_basic.exe` (exit code: 1)  </pre>



<p>例では、<code>fs::read_to_string</code> によって <code>std::io::Error</code> が発生しています。通常であれば、このエラー型にあわせて処理を実装する必要があります。</p>



<p>しかし、<code>main</code> 関数の戻り値は <code>anyhow::Result&lt;()&gt;</code>（= <code>Result&lt;(), anyhow::Error&gt;</code>）としているため、自動的に <code>anyhow::Error</code> に変換され、? 演算子により上位へ返却されます。このように、エラー型を意識せずに <code>?</code> を使えることが、<code>anyhow</code> を使用する大きなメリットです。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><strong>【<code>anyhow::Error</code> に自動変換できる条件】</strong></p>



<p><code>?</code> 演算子によって自動的に <code>anyhow::Error</code> に変換して伝播できるかどうかは、返却されるエラー型により決まります。自動変換のためには、呼び出し先のエラーは以下を満たす必要があります。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ul class="wp-block-list jinr-list">
<li><code>std::error::Error</code> を実装している</li>



<li><code>Send + Sync + 'static</code> のトレイト境界を満たす</li>
</ul>
</div></div></section>



<p>標準ライブラリのエラー型は、多くの場合で上記制約を満たすのであまり意識する必要なく使えることがほとんどです。</p>



<p>また、 <code>thiserror</code> により作成した独自エラー型も <code>String</code> のような所有型・スレッドセーフな型で構成していれば、通常は自然に制約を満たします。ただし <code>&amp;str</code> などの参照含む場合などでは条件を満たせない場合があります。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold"><code>context</code> / <code>with_context</code> で文脈情報（コンテキスト）を追加する</h3>



<p>? を使用したエラー伝播は非常に簡潔で便利ですが、そのままではどの処理で失敗したのかが分かりづらくなってしまう場合があります。このような場合に便利なのが、<code>Context</code> トレイトが提供する <span class="jinr-d--text-color d--marker1 d--bold"><code>context</code></span> および <span class="jinr-d--text-color d--marker1 d--bold"><code>with_context</code></span> です。</p>



<p>これらを使うことで、エラー発生時に追加の文脈情報（コンテキスト）を付与することができ、原因調査をしやすくなります。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>context</code> で固定のメッセージを追加する</h4>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>context</code></span> を使用することで以下のように固定のメッセージを追加することができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use anyhow::{Context, Result};
use std::fs;

fn main() -> Result&lt;()> {
    let path = "input_file.txt";

    // コンテキスト情報を追加してエラーを返す
    let content =
        fs::read_to_string(path).context("[main] テキストファイルの読み込みに失敗しました。")?;

    println!("{content}");

    Ok(())
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Error: [main] テキストファイルの読み込みに失敗しました。

Caused by:
    指定されたファイルが見つかりません。 (os error 2)
error: process didn't exit successfully: `D:\RustProject\rust-tech-sample-source\target\debug\examples\anyhow_context.exe` (exit code: 1)</pre>



<p>例のように <code>context</code> を使用すると、元のエラーに対して固定のメッセージを追加することができます。実行結果を見ると、最初に追加したメッセージが表示されており、その下の「Caused by:」以下に元のエラーが保持されていることが分かります。</p>



<p>このように、<code>anyhow</code> は元のエラー情報を失うことなく、追加の文脈情報（コンテキスト）を積み重ねて保持することができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>with_context</code> で動的にメッセージを生成して追加する</h4>



<p><code>context</code> は固定メッセージを追加する方法でしたが、<span class="jinr-d--text-color d--marker1 d--bold"><code>with_context</code></span> を使用すると、以下のように動的にメッセージを生成して追加することができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use anyhow::{Context, Result};
use std::fs;

fn main() -> Result&lt;()> {
    let path = "input_file.txt";

    // クロージャーを使って動的にコンテキスト情報を追加してエラーを返す
    let content = fs::read_to_string(path)
        .with_context(|| format!("[main] テキストファイルの読み込みに失敗しました。path={path}"))?;

    println!("{content}");

    Ok(())
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Error: [main] テキストファイルの読み込みに失敗しました。path=input_file.txt

Caused by:
    指定されたファイルが見つかりません。 (os error 2)
error: process didn't exit successfully: `D:\RustProject\rust-tech-sample-source\target\debug\examples\anyhow_with_context.exe` (exit code: 1)</pre>



<p><code>with_context</code> は、クロージャーを受け取り、エラーが発生した場合にのみ処理を実行します。そのため、例のように <code>format!</code> マクロを使って変数を埋め込んだ動的なメッセージを生成したい場合などに向いています。</p>



<p><code>context</code> と <code>with_context</code> は似ていますが、使い分けは以下のように整理できます。</p>



<ul class="wp-block-list jinr-list">
<li><code>context</code>：固定のメッセージを追加したい場合</li>



<li><code>with_context</code>：エラー発生時に処理を行い、動的なメッセージを生成したい場合</li>
</ul>



<h3 class="wp-block-heading jinr-heading d--bold"><code>anyhow!</code> / <code>bail!</code> マクロで自分でエラーを作る</h3>



<p>これまでは、下位の処理が返却するエラーを ? 演算子で伝播する例を見てきました。一方で、アプリケーション側の条件チェックなどにより自分でエラーを生成したい場合もよくあります。</p>



<p>このような場合には、<span class="jinr-d--text-color d--marker1 d--bold"><code>anyhow!</code></span> マクロや <span class="jinr-d--text-color d--marker1 d--bold"><code>bail!</code></span> マクロの使用が便利です。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>anyhow!</code> マクロで <code>anyhow::Error</code> を生成する</h4>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>anyhow!</code></span> マクロを使用することで以下のように <code>anyhow::Error</code> を生成することができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use anyhow::{Result, anyhow};

fn main() -> Result&lt;()> {
    let path = "";

    if path.is_empty() {
        // エラーを生成する
        let err = anyhow!("[main] パスが空です。");

        // エラーを返却する
        return Err(err);
    }

    Ok(())
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Error: [main] パスが空です。
error: process didn't exit successfully: `D:\RustProject\rust-tech-sample-source\target\debug\examples\anyhow_anyhow_macro.exe` (exit code: 1)</pre>



<p>例のように、<code>anyhow!</code> マクロにより <code>anyhow::Error</code> 型の値を生成することができ、変数に代入して扱うことができます。これにより、ログ出力などの追加の処理をしてから「<code>return Err(err)</code>」のように返却するといったことが可能になります。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>bail!</code> マクロで <code>anyhow::Error</code> を生成し、即時返却する</h4>



<p><code>anyhow!</code> マクロでは一度変数に代入して扱いましたが、場合によってはエラー発生時に即時に <code>return</code> すればいい場合があります。このような場合には、<span class="jinr-d--text-color d--marker1 d--bold"><code>bail!</code></span> マクロを使用することでコードがより簡潔に書くことができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use anyhow::{Result, bail};

fn main() -> Result&lt;()> {
    let path = "";

    if path.is_empty() {
        // エラーを生成して、即時に返却する
        bail!("[main] パスが空です。");
    }

    Ok(())
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Error: [main] パスが空です。
error: process didn't exit successfully: `D:\RustProject\rust-tech-sample-source\target\debug\examples\anyhow_bail_macro.exe` (exit code: 1)</pre>



<p>例のように <code>bail!</code> マクロは <code>anyhow::Error</code> を生成し、その場で <code>Err</code> を返却しています。そのため、<code>return</code> の記載も必要なくなり非常に簡潔にコードを各ことができます。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust で <span class="jinr-d--text-color d--marker1 d--bold"><code>anyhow</code> を用いて複数のエラーをまとめて扱う方法</span>について解説しました。</p>



<p><code>anyhow</code> を使用することでアプリケーション側ではエラー型を 1 つに統一し、<code>?</code> 演算子によるエラー伝播を簡潔に記述できます。</p>



<p>また、<code>context</code> / <code>with_context</code> を使用することでエラーに追加の文脈情報（コンテキスト）を追加することで原因調査もしやすくなります。さらに、<code>anyhow!</code> や <code>bail!</code> といったマクロを使うことで、自分でエラー生成をして扱うことも簡単です。</p>



<p><code>anyhow</code> は、エラー型を厳密にするためのクレートではなく、アプリケーション側でのエラー運用をしやすくしてくれるクレートです。ライブラリ側では、<code>thiserror</code> による独自エラー型を設計し、アプリケーション側では <code>anyhow</code> を使って統一的にエラーを扱うという使い分けをすると非常に効率的に開発を進められると思います。</p>



<p>ぜひ、<code>anyhow</code> の使い方の基本をしっかりと覚えてもらえたらと思います。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>anyhow</code> のドキュメントは<a href="https://docs.rs/anyhow/latest/anyhow/" target="_blank" rel="noreferrer noopener">こちら</a>を参考にしてください。</p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>thiserror</code> については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-thiserror-error-types/" target="_blank" rel="noreferrer noopener">thiserrorにより独自のエラー型を実装する方法</a></p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-libraries/anyhow-basic" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section><div id="nkhn3-306419380" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-anyhow-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust】thiserrorにより独自のエラー型を実装する方法</title>
		<link>https://rust-tech.nkhn37.net/rust-thiserror-error-types/</link>
					<comments>https://rust-tech.nkhn37.net/rust-thiserror-error-types/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sun, 25 Jan 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[thiserror]]></category>
		<category><![CDATA[anyhow]]></category>
		<category><![CDATA[derive]]></category>
		<category><![CDATA[From]]></category>
		<category><![CDATA[Result型]]></category>
		<category><![CDATA[transparent]]></category>
		<category><![CDATA[エラー処理]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1635</guid>

					<description><![CDATA[Rust で thiserror を用いて独自のエラー型を実装する方法について、初心者にも分かりやすく解説します。 thiserror クレートの概要 thiserror とは Rust で独自のエラー型を定義する場合、 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust で <span class="jinr-d--text-color d--marker1 d--bold"><code>thiserror</code> を用いて独自のエラー型を実装する方法</span>について、初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold"><code>thiserror</code> クレートの概要</h2>



<h3 class="wp-block-heading jinr-heading d--bold"><code>thiserror</code> とは</h3>



<p>Rust で独自のエラー型を定義する場合、<code>std::error::Error</code> トレイトや <code>std::fmt::Display</code> トレイトの実装が必要となり、エラーの種別が増えるほどボイラープレートコードという定型的なコードが増えていってしまいます。</p>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>thiserror</code></span> は、独自のエラー型の実装を簡潔に書けるようにする便利なクレートです。</p>



<p>この記事では、<span class="jinr-d--text-color d--marker1 d--bold"><code>thiserror</code> を使った独自エラー型の定義方法の基本</span>について紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>thiserror</code> の特徴（<code>derive</code> でエラー型の実装を簡素化する）</h3>



<p><code>thiserror</code> を使用する上で最低限理解したい内容としては以下です。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ul class="wp-block-list jinr-list">
<li><code>#[derive(Error)]</code> で <code>std::error::Error</code> を実装でき、<code>#[error("...")]</code> に基づいて <code>std::fmt::Display</code> も自動生成される。</li>



<li><code>#[from]</code> により、エラー変換（<code>From</code>）を自動実装できる。</li>



<li><code>#[error(transparent)]</code> により、薄いラッパー型を簡潔に定義できる。</li>
</ul>
</div></div></section>



<p>以降では、上記について例を用いて紹介していきます。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>thiserror</code> の位置づけ（<code>Result&lt;T, E&gt;</code> や <code>anyhow</code> との関係性）</h3>



<p>Rust では、<code>Result&lt;T, E&gt;</code> という結果型を用いた明示的なエラー処理が基本です。<code>T</code> や <code>E</code> は、型パラメータであり、任意の型とすることができます。<code>thiserror</code> は、この <code>E</code> に使う「独自のエラー型」を定義しやすくするためのクレートです。</p>



<p>また、Rust のエラー処理では、<code>anyhow</code> というクレートもよく聞きます。各種クレートなどの様々な機能を使用する場合、それらの機能が独自に設計しているエラー型を扱う場合があります。この時、全てのエラー型を意識して実装するのは大変です。<code>anyhow</code> は、様々なエラー型をまとめて取り扱うことができます。</p>



<p><code>thiserror</code> と <code>anyhow</code> の位置づけは以下のように理解しておいてもらうといいかと思います。</p>



<ul class="wp-block-list jinr-list">
<li><code>thiserror</code>：独自のエラー型を簡単に定義する。</li>



<li><code>anyhow</code>：様々なエラー型をまとめて取り扱うことができる。</li>
</ul>



<p>一般的には、ライブラリ側では <code>thiserror</code>、アプリケーション側では <code>anyhow</code> が使われることが多いです。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>エラー処理の基本や <code>anyhow</code> については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-error-handling-basic/" target="_blank" rel="noreferrer noopener">エラー処理の基本を分かりやすく解説</a></p>



<p><a href="https://rust-tech.nkhn37.net/rust-anyhow-basic/" target="_blank" rel="noreferrer noopener">anyhow で複数のエラーをまとめて扱う方法</a></p>
</div>
		</div></section>



<div id="nkhn3-1623951887" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold"><code>thiserror</code> の基本</h2>



<h3 class="wp-block-heading jinr-heading d--bold"><code>thiserror</code> の導入方法</h3>



<p><code>thiserror</code> は他クレート同様に <code>cargo add</code> または <code>Cargo.toml</code> に追記することで利用できるようになります。</p>



<p><strong>【<code>cargo add</code> で追加する場合】</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo add thiserror</pre>



<p><strong>【<code>Cargo.toml</code> に追記する場合】</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[dependencies]
thiserror = "2.0.18"</pre>



<p>例での記載バージョンは、記事執筆時点での最新バージョンで記載しているため、導入時には crates.io の <a href="https://crates.io/crates/thiserror" target="_blank" rel="noreferrer noopener"><code>thiserror</code> のページ</a>を確認して指定してください。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>クレートや依存関係の基本については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-crates-basics/" target="_blank" rel="noreferrer noopener">クレート（バイナリ／ライブラリ）と依存関係の管理を分かりやすく解説</a></p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">独自エラー型の定義方法（基本）</h3>



<p><code>thiserror</code> の基本的な使い方を以下の例で見ていきましょう。以下の例では、独自の <code>MyError</code> というエラー型を作成しています。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="3-11" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use thiserror::Error;

// 独自エラー型の定義
#[derive(Error, Debug)]
enum MyError {
    #[error("不正な入力です。")]
    InvalidInput,

    #[error("権限がありません。")]
    PermissionDenied,
}

fn main() {
    // 不正な入力エラー
    let err = MyError::InvalidInput;
    println!("{err}");
    println!("{err:?}");

    // 権限拒否エラー
    let err = MyError::PermissionDenied;
    println!("{err}");
    println!("{err:?}");
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
不正な入力です。
InvalidInput
権限がありません。
PermissionDenied</pre>



<p>上記例の独自エラー型は列挙型（<code>enum</code>）で定義しており、不正な入力を意味する <code>InvalidInput</code> と権限がないことを意味する <code>PermissionDenied</code> というバリアントを持っている型です。</p>



<p><code>thiserror</code> を使用するには、まず「<code>use thiserror::Error</code>」をスコープに取り込みます。独自のエラー型に <span class="jinr-d--text-color d--marker1 d--bold"><code>#[derive(Error, Debug)]</code></span> をつけることで独自の型に各種トレイトを自動実装しています。</p>



<p><code>#[derive(Error)]</code> により、<code>std::error::Error</code> トレイトが実装され、各バリアントに記載された <span class="jinr-d--text-color d--marker1 d--bold"><code>#[error("...")]</code></span> のエラーメッセージに基づいて <code>std::fmt::Display</code> トレイトの自動実装も行われています。また、<code>#[derive(Debug)]</code> では、<code>std::fmt::Debug</code> トレイトの自動実装が行われています。</p>



<p><code>main</code> 関数では、この独自エラー型を生成して表示してみていますが、<code>Display</code> トレイトが実装されることで、独自に作ったエラー表示ができていることが分かるかと思います。なお、<code>Debug</code> トレイトの自動実装では、バリアント名や保持している値が表示されるようになります。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>列挙型やトレイトの基本については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-enum-basic/" target="_blank" rel="noreferrer noopener">列挙型の基本を分かりやすく解説</a></p>



<p><a href="https://rust-tech.nkhn37.net/rust-trait-basic/" target="_blank" rel="noreferrer noopener">トレイトの基本を分かりやすく解説</a></p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">引数によりエラーに情報を持たせる</h3>



<p><code>thiserror</code> を使って構築するエラー型では、エラーの原因を調査しやすくするために、エラーに関連するような情報を引数として渡して受け取ることができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="6,9,15,20" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use thiserror::Error;

// 独自エラー型の定義 引数付き
#[derive(Error, Debug)]
enum MyError {
    #[error("不正な入力です: {0}")]
    InvalidInput(String),

    #[error("権限がありません: ID {user_id}")]
    PermissionDenied { user_id: u32 },
}

fn main() {
    // 不正な入力エラー
    let err = MyError::InvalidInput("空の文字列".to_string());
    println!("{err}");
    println!("{err:?}");

    // 権限拒否エラー
    let err = MyError::PermissionDenied { user_id: 42 };
    println!("{err}");
    println!("{err:?}");
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
不正な入力です: 空の文字列
InvalidInput("空の文字列")
権限がありません: ID 42
PermissionDenied { user_id: 42 }</pre>



<p>例では、<code>#[error("...")]</code> 内で指定する文字列に、引数を埋め込むように指定することができます。引数の指定については、値を直接持たせる形式（tuple variant）とフィールド名付きの形式（struct variant）の大きく 2 種類があります。</p>



<p>値を直接持たせる形式（tuple variant）の場合には、エラー文字列の埋め込む位置に <code>{0}</code>, <code>{1}</code>, &#8230; のように記載し、引数として渡された順に値が埋め込まれます。複数の引数を渡す場合には「<code>,</code>」で列挙して渡します。</p>



<p>フィールド名付きの形式（struct variant）の場合には、エラー文字列の埋め込む位置に <code>{user_id}</code>  のようにフィールド名を記載します。引数を渡す際には <code>{ user_id: 42 }</code> のようにフィールドと値を設定して渡します。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>#[from]</code> によるエラー変換</h3>



<p>独自のエラー型は、ある関数やメソッドの返却値として使用します。当該関数やメソッドで下位のモジュールを使用する場合、下位からもエラーが返却されることがあります。この場合、エラーをその場で処理せずに上位へ伝播する際に Rust では「<code>?</code>」をよく使用します。</p>



<p>この時に、下位のエラーを独自のエラー型に変換して伝播したい場合は、<span class="jinr-d--text-color d--marker1 d--bold"><code>#[from]</code></span> により独自エラー型へ型変換すると便利です。具体的には「<code>impl From&lt;std::io::Error&gt; for MyError</code>」が自動生成されます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="7-8" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::fs;
use thiserror::Error;

#[derive(Error, Debug)]
enum MyError {
    // std::io::Error から自動的に変換されるエラー
    #[error("My I/Oエラーが発生: {0}")]
    Io(#[from] std::io::Error),
}

// ファイルを読み込む関数
fn my_read_file(path: &amp;str) -> Result&lt;String, MyError> {
    // fs::read_to_string は std::io::Error を返却するが、
    // #[from] により MyError に自動変換される
    let content = fs::read_to_string(path)?;
    Ok(content)
}

fn main() {
    match my_read_file("non_existent_file.txt") {
        Ok(content) => println!("ファイル内容: {content}"),
        Err(e) => {
            println!("エラー : {e}");
            println!("デバッグ情報: {e:?}");
        }
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
エラー : My I/Oエラーが発生: 指定されたファイルが見つかりません。 (os error 2)
デバッグ情報: Io(Os { code: 2, kind: NotFound, message: "指定されたファイルが見つかりません。" })</pre>



<p>例では、<code>my_read_file</code> という関数でファイルを読み込もうとしていますが、ファイルが開けない場合などでは、<code>std::io::Error</code> が返却されてきます。</p>



<p>このエラーを独自エラー型に変換する場合は、「<code>Io(#[from] std::io::Error)</code>」の部分のように記載します。これは、<code>Io</code> バリアントに <code>std::io::Error</code> を詰めていることを表していて、<code>#[error("...")]</code> 内の <code>{0}</code> の部分には、<code>std::io::Error</code> のエラー表示が埋め込まれます。</p>



<p>このようにして、下位エラーを <code>MyError</code> に変換し、<code>Result&lt;T, MyError&gt;</code> の <code>Err(...)</code> として返却できるようになります。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>#[error(transparent)]</code> により透過的にエラーを扱う</h3>



<p>上記の <code>#[from]</code> の例では、下位のモジュールのエラーを独自エラー型に変換しました。場合によっては、下位のモジュールのエラー内容をそのまま利用するだけで十分な場合があります。そのような場合は、以下のように「<span class="jinr-d--text-color d--marker1 d--bold"><code>#[error(transparent)]</code></span>」を使用するのが便利です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="7" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::fs;
use thiserror::Error;

#[derive(Error, Debug)]
enum MyError {
    // 下位のエラーをそのまま伝搬させる
    #[error(transparent)]
    Io(#[from] std::io::Error),
}

// ファイルを読み込む関数
fn my_read_file(path: &amp;str) -> Result&lt;String, MyError> {
    let content = fs::read_to_string(path)?;
    Ok(content)
}

fn main() {
    match my_read_file("non_existent_file.txt") {
        Ok(content) => println!("ファイル内容: {content}"),
        Err(e) => {
            println!("エラー : {e}");
            println!("デバッグ情報: {e:?}");
        }
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
エラー : 指定されたファイルが見つかりません。 (os error 2)
デバッグ情報: Io(Os { code: 2, kind: NotFound, message: "指定されたファイルが見つかりません。" })</pre>



<p><code>transparent</code> とは「透明」という意味で、独自のエラーなのに下位のエラーが透過的にみえるというイメージを持ってもらうと分かりやすいかと思います。薄いラッパーのエラー型を作りたい場合には、非常によく使われる方法です。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>この記事では、Rust で <span class="jinr-d--text-color d--marker1 d--bold"><code>thiserror</code> を用いて独自のエラー型を実装する方法</span>について、初心者向けに解説しました。</p>



<p><code>thiserror</code> を使用することで独自エラー型を実装する際に発生しがちなボイラープレートコードを削減しつつ、<code>Result&lt;T, E&gt;</code> の <code>E</code> に適したエラー型を自然な形で設計できます。</p>



<p><code>thiserror</code> の入門として最低限押さえておきたいポイントは以下の通りです。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ul class="wp-block-list jinr-list">
<li><code>#[derive(Error)]</code> で <code>std::error::Error</code> を実装でき、<code>#[error("...")]</code> に基づいて <code>std::fmt::Display</code> も自動生成される。</li>



<li><code>#[from]</code> により、エラー変換（<code>From</code>）を自動実装できる。</li>



<li><code>#[error(transparent)]</code> により、薄いラッパー型を簡潔に定義できる。</li>
</ul>
</div></div></section>



<p>また、エラー処理関連でよく紹介される <code>anyhow</code> については、一般的に以下のような使い分けがされます。</p>



<ul class="wp-block-list jinr-list">
<li>ライブラリ／モジュール側：<code>thiserror</code> による独自エラー型を定義</li>



<li>アプリケーション側：<code>anyhow</code> による複数エラーの統一的な取り扱い</li>
</ul>



<p>ぜひ、<code>thiserror</code> をうまく活用して、扱いやすい独自エラー型を実装してみてください。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>thiserror</code> のドキュメントは<a href="https://docs.rs/thiserror/latest/thiserror/" target="_blank" rel="noreferrer noopener">こちら</a>を参照してください。</p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p><code>anyhow</code> については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-anyhow-basic/" target="_blank" rel="noreferrer noopener">anyhow で複数のエラーをまとめて扱う方法</a></p>
</div>
		</div></section>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-libraries/thiserror-basic" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section>


<p></p>
<div id="nkhn3-2515918612" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-thiserror-error-types/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】モジュールの可視性の基本を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-modules-visibility-basic/</link>
					<comments>https://rust-tech.nkhn37.net/rust-modules-visibility-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 16 Jan 2026 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[mod]]></category>
		<category><![CDATA[pub]]></category>
		<category><![CDATA[use]]></category>
		<category><![CDATA[モジュール]]></category>
		<category><![CDATA[可視性]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1565</guid>

					<description><![CDATA[Rust のモジュールの可視性の基本を初心者にも分かりやすく解説します。 Rust のモジュールの可視性 Rust では、コードを整理して安全性を高めるために「モジュール」と「可視性（visibility）」という仕組み [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust の<span class="jinr-d--text-color d--marker1 d--bold">モジュールの可視性</span>の基本を初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">Rust のモジュールの可視性</h2>



<p>Rust では、コードを整理して安全性を高めるために「<span class="jinr-d--text-color d--marker1 d--bold">モジュール</span>」と「<span class="jinr-d--text-color d--marker1 d--bold">可視性（visibility）</span>」という仕組みが用意されています。この仕組みの中でも「<span class="jinr-d--text-color d--marker1 d--bold"><code>pub</code></span>」は、モジュール間やクレート間での参照をうまく制御するための重要なキーワードです。</p>



<p>Rust は、安全性を高めるため「<span class="jinr-d--text-color d--marker1 d--bold">モジュール外から参照できる要素はデフォルトで非公開</span>」となっているという特徴があります。そのため、外部に公開したいものには <code>pub</code> をつけて開発者が明示的に公開範囲を示す必要があります。</p>



<p>この記事では、Rust のモジュール構造を説明しながら、<code>pub</code> を中心とした可視性の仕組みを初心者にも分かりやすく紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">Rust のモジュールとは</h3>



<p>Rust では、コードを階層的に分割し、相互の機能を隠ぺい、公開するための強力な<span class="jinr-d--text-color d--marker1 d--bold">モジュール</span>システムがあります。モジュールは、関数、構造体、定数などを論理的にまとめることができ、<span class="jinr-d--text-color d--marker1 d--bold"><code>mod</code></span> キーワードを使って以下のように定義します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// ファイル内でのモジュール定義例
mod sample_mod {
    // 公開関数
    pub fn hello() {
        println!("[sample_mod] 公開関数");
    }
}

fn main() {
    println!("===== ファイル内でのモジュール定義例 =====");
    sample_mod::hello();
}</pre>



<p>この <code>sample_mod</code> モジュールは、<code>main.rs</code> のファイル内で定義されているモジュールであるとします。例では、<code>sample_mod</code> に <code>hello()</code> という関数が定義されていることを意味します。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>pub</code> による公開</h3>



<p>Rust の大きな特徴として「<span class="jinr-d--text-color d--marker1 d--bold"><span class="jinr-d--text-color d--marker1 d--bold">モジュール外から参照できる要素はデフォルトで非公開</span></span>」となっています。そのため、<code>mod</code> で定義したモジュール内の要素をスコープ外に公開したい場合には、<span class="jinr-d--text-color d--marker1 d--bold"><code>pub</code></span> キーワードをつけて公開（<code>public</code>）であることを明示します。</p>



<p>上記の例で「<code><span class="jinr-d--text-color d--marker1 d--bold">pub</span> fn hello() { ... }</code>」は、<code>mod</code> の <code>{}</code> で囲われたスコープの外に <code>hello()</code> 関数を公開していることを意味します。モジュール <code>sample_mod</code> は、名前空間として機能するため <code>main.rs</code> 内の関数（<code>main</code> 関数など）から、<code>hello()</code> 関数を使用するには、<code>sample_mod::hello()</code> のように「::」を使用して呼び出します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">デフォルトは<code>非公開</code></h3>



<p>Rust の大きな特徴として「<span class="jinr-d--text-color d--marker1 d--bold">すべての要素はデフォルトで <code>private</code>（非公開）</span>」となっています。そのため、以下のように <code>mod</code> のスコープ外から内部で <code>pub</code> をつけずに定義した関数へアクセスしようとするとコンパイルエラーとなります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="9" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// ファイル内でのモジュール定義例
mod sample_mod {
    // 公開関数
    pub fn hello() {
        println!("[sample_mod] 公開関数");
        private_hello();
    }

    // 非公開関数
    fn private_hello() {
        println!("[sample_mod] 非公開関数");
    }
}

fn main() {
    println!("===== ファイル内でのモジュール定義例 =====");
    sample_mod::hello();
    // 以下の非公開関数の呼び出しはエラーになる
    // sample_mod::private_hello();
}</pre>



<p>例では、<code>private_hello</code> は、非公開関数であり、<code>sample_mod</code> モジュールの中でしか使用できません。そのため、スコープ外の <code>main</code> 関数から呼び出すとコンパイルエラーとなります。</p>



<p>一方で、<code>hello</code> 関数は、モジュール内の関数なので、この関数からは <code>private_hello</code> 関数へアクセスすることが可能です。このようにすることで、モジュールの外部に公開する関数を制御することが可能です。</p>



<div id="nkhn3-1875200126" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">モジュールの分割と管理方法</h2>



<p>Rust では、モジュール定義を <code>mod</code> 宣言により行いますが、その実体をファイルやディレクトリに分割することができます。Rust でよく使われるモジュール分割方法には次のようなものがあります。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ul class="wp-block-list jinr-list">
<li>ファイル単位でモジュールを分割する方法</li>



<li>ファイルとディレクトリを組み合わせてサブモジュールを管理する方法</li>



<li><code>mod.rs</code> を使用する従来の方法（現在も使用可能）</li>
</ul>
</div></div></section>



<p>以降では、基本的な方法から順に説明していきます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">ファイル単位でモジュールを分割する方法</h3>



<p>まずは、基本となるファイル単位でモジュールを分割する方法を説明します。以下のように <code>main.rs</code> とは別に <code>module1.rs</code> を用意した例で紹介します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">src/
├── main.rs      // エントリポイント
└── module1.rs   // module1 モジュール</pre>



<p>以下のようなプログラムを用いて詳細を説明します。</p>



<p><strong>[<code>main.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// モジュール読み込み
mod module1; // ファイルで分割

fn main() {
    println!("\n===== ファイルで分割する例 (module1) =====");
    module1::hello();
    // 以下の非公開関数の呼び出しはエラーになる
    // module1::private_hello();
    module1::submod::hello();
    module1::submod::nested::nested_hello();
}</pre>



<p><strong>[<code>module1.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 公開関数
pub fn hello() {
    println!("[module1] 公開関数");
    private_hello();
    private_mod::hello();
}

// 非公開関数
fn private_hello() {
    println!("[module1] 非公開関数");
}

// 公開サブモジュール
pub mod submod {
    // サブモジュール内の公開関数
    pub fn hello() {
        println!("[module1::submod] サブモジュール内の公開関数");
        private_hello();
    }

    // サブモジュール内の非公開関数
    fn private_hello() {
        println!("[module1::submod] サブモジュール内の非公開関数");
    }

    // ネストされた公開サブモジュール
    pub mod nested {
        pub fn nested_hello() {
            println!("[module1::submod::nested] ネストされたサブモジュール内の公開関数");
        }
    }
}

// 非公開のサブモジュール
mod private_mod {
    pub fn hello() {
        println!("[module1::private_mod] 非公開のサブモジュール");
    }
}</pre>



<p><code>main.rs</code> で <code>module1</code> を使用するには、ファイルの先頭で次のように宣言します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mod module1;</pre>



<p>この宣言により、<code>module1.rs</code> は <code>module1</code> モジュールとして読み込まれて、<code>module1::関数名</code> のように公開要素を利用できるようになります。</p>



<p><code>module1.rs</code> 内では、複数の関数とサブモジュールを定義しています。<code>hello</code> 関数は、<code>pub</code> をつけて定義しているため、main.rs のような外部モジュールから呼び出すことができます。一方、<code>private_hello</code> 関数は <code>pub</code> をつけていないため、<code>module1</code> の内部からのみ利用可能です。</p>



<p>また、モジュール内ではさらにサブモジュールを定義することができます。<code>submod</code> は、<code>module1</code> の公開サブモジュールであり、外部からもアクセス可能です。さらに、その中に <code>nested</code> のようなネストしたサブモジュールを定義することもできます。</p>



<p>注意点として、サブモジュールも「<code>pub mod</code>」としない限り外部には公開されません。<code>private_mod</code> は、<code>pub</code> が付いていないため、<code>module1</code> の内部からしか利用できないモジュールです。</p>



<p>このように、意味のある単位でモジュールを分割し、可視性を適切に制御することで、コードの構造を整理し、安全で見通しの良いプログラムを作成することができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">ディレクトリでサブモジュールを管理する方法</h3>



<p>プロジェクトが大きくなってきた際に、1 つのファイルにすべてのサブモジュールを定義すると構造が分かりにくくなります。そのような場合には、ディレクトリを使ってサブモジュールを分割すると構造が明確になり、保守性も向上します。</p>



<p>以下のような構成を考えます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">src/
├── main.rs      // エントリポイント
├── module2.rs   // module2 モジュール
└── module2/
    ├── submod_1.rs  // サブモジュール1
    └── submod_2.rs  // サブモジュール2</pre>



<p><strong>[<code>main.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// モジュール読み込み
mod module2; // ディレクトリでサブモジュールを管理する

fn main() {
    println!("\n===== ディレクトリでサブモジュールを管理する例 (module2) =====");
    module2::submod_1::hello();
    module2::submod_2::hello();
}
</pre>



<p><strong>[<code>module2.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pub mod submod_1;
pub mod submod_2;</pre>



<p><strong>[<code>submod_1.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 公開関数
pub fn hello() {
    println!("[module2::submod_1] 公開関数");
    private_hello();
}

// 非公開関数
fn private_hello() {
    println!("[module2::submod_1] 非公開関数");
}</pre>



<p><strong>[<code>submod_2.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 公開関数
pub fn hello() {
    println!("[module2::submod_2] 公開関数");
    private_hello();
}

fn private_hello() {
    println!("[module2::submod_2] 非公開関数");
}</pre>



<p>この構成では、<code>module2.rs</code> が <code>module2</code> モジュールのエントリーポイントになります。<code>module2</code> ディレクトリ配下に配置したファイルについては、<code>module2.rs</code> 内で <code>mod</code> 宣言することでサブモジュールとして読み込まれます。</p>



<p>なお、ディレクトリにファイルを配置しただけでは、自動的にモジュールにはなりません。親モジュール側（この例では、<code>module2.rs</code>）で <code>mod</code> 宣言する必要がある点に注意してください。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>mod.rs</code> を使用する従来の方法</h4>



<p>以前の Rust では、ディレクトリをモジュールとして扱う場合、<span class="jinr-d--text-color d--marker1 d--bold"><code>mod.rs</code></span> を配置する方法が一般的でした。現在でも使用可能ですが、新規プロジェクトでは前述の「ファイル + ディレクトリ」を組み合わせた方法が使われることが多くなっています。</p>



<p><code>mod.rs</code> は以下のようにモジュール名のディレクトリ配下に配置します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">src/
├── main.rs      // エントリポイント
└── module3/
    ├── mod.rs       // module3 モジュール
    ├── submod_1.rs  // サブモジュール1
    └── submod_2.rs  // サブモジュール2</pre>



<p><strong>[<code>main.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// モジュール読み込み
mod module3; // mod.rs を使用する従来の方法

fn main() {
    println!("\n===== mod.rs を使用する従来の方法例 (module3) =====");
    module3::submod_1::hello();
    module3::submod_2::hello();
}</pre>



<p><strong>[<code>mod.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pub mod submod_1;
pub mod submod_2;</pre>



<p><code>submod_1.rs</code> と <code>submod_2.rs</code> は先ほどの例と同様なので省略します。</p>



<h3 class="wp-block-heading jinr-heading d--bold"><code>use</code> によるモジュールのスコープへの取り込み</h3>



<p>これまでの例では、<code>module::submodule::function</code> のようにフルパスでモジュールの構成要素を呼び出していました。<code>use</code> を使うことで、指定した要素をスコープに取り込み、より簡潔に記述できます。</p>



<p><strong>[<code>main.rs</code>]</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// モジュール読み込み
mod module1; // ファイルで分割
mod module2; // ディレクトリでサブモジュールを管理する

// use 宣言でモジュールをスコープに取り込む
use module1::submod::hello;
use module2::submod_1::hello as hello_module2_submod_1;

fn main() {
    println!("\n===== use 宣言でスコープに取り込む例 =====");
    hello();
    hello_module2_submod_1();
}
</pre>



<p>同名の要素をスコープに取り込む場合には、<code>as</code> を使って別名をつける必要があります。</p>



<p>なお、use は名前解決を簡単にするための仕組みであり、可視性に直接かかわるものではありません。モジュールを使用するためには、<code>mod</code> でモジュールを取り込む必要があることに注意してください。</p>



<h3 class="wp-block-heading jinr-heading d--bold">その他の <code>pub</code> の指定方法</h3>



<p>これまでに紹介したように、基本的には <code>pub</code> を使った公開指定の方法とモジュール分割の方法を理解しておけば多くの場合では問題ありません。より細かく公開範囲を指定したい場合には、次のような指定方法も用意されています。</p>



<ul class="wp-block-list jinr-list">
<li><code>pub(super)</code>：親モジュールまで公開する</li>



<li><code>pub(in <em>path</em>)</code>：指定したモジュールパス (<code><em>path</em></code>) 内のみに公開</li>
</ul>



<p>この記事では詳細な説明は省略しますが、公開範囲を段階的に制御できる仕組みがあるという点は押さえておいてください。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust の<span class="jinr-d--text-color d--marker1 d--bold">モジュールの可視性</span>の基本について解説しました。</p>



<p>Rust では、モジュール外から参照できる要素はデフォルトで非公開となっており、外部に公開したい関数や型には <code>pub</code> を付けて明示的に公開範囲を指定します。この仕組みにより、意図しない API の公開を防ぎ、安全で保守しやすいコードを書くことができます。</p>



<p>また、モジュールは <code>mod</code> 宣言を用いて定義し、その実体をファイルやディレクトリに分割して管理することが可能です。プロジェクトの規模に応じて、ファイル単位やディレクトリ単位でモジュールを整理すると、コードの見通しが良くなります。</p>



<p>さらに、<code>use</code> を使うことでモジュールの要素をスコープに取り込み、記述を簡潔にすることができます。ただし、<code>use</code> は可視性のルール自体を変更するものではない点には注意が必要です。</p>



<p>まずは、この記事で紹介した <code>pub</code> による公開と基本的なモジュール分割の方法をしっかり理解することで、Rust のモジュール設計の基礎を覚えていただければと思います。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/visibility" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section>


<p></p>
<div id="nkhn3-901466243" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-modules-visibility-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】クレート（バイナリ／ライブラリ）と依存関係の管理を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-crates-basics/</link>
					<comments>https://rust-tech.nkhn37.net/rust-crates-basics/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 13 Dec 2025 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[cargo]]></category>
		<category><![CDATA[Cargo.toml]]></category>
		<category><![CDATA[crates.io]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[クレート]]></category>
		<category><![CDATA[セマンティックバージョニング]]></category>
		<category><![CDATA[パッケージ管理]]></category>
		<category><![CDATA[依存関係]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1532</guid>

					<description><![CDATA[Rust におけるクレートと依存関係の管理について初心者にも分かりやすく解説します。 Rust のクレート クレートとは？ Rust におけるクレート（crate）とは、コンパイル可能な最小単位のコードのまとまりのことで [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クレート</span>と<span class="jinr-d--text-color d--marker1 d--bold">依存関係の管理</span>について初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">Rust のクレート</h2>



<h3 class="wp-block-heading jinr-heading d--bold">クレートとは？</h3>



<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クレート（crate）</span>とは、コンパイル可能な最小単位のコードのまとまりのことです。Rust のプログラムは、必ず 1 つ以上のクレートによって構成されており、Cargo を使用してプロジェクトを作成すると自動的にクレートが生成されます。</p>



<p>クレートの種類には「<span class="jinr-d--text-color d--marker1 d--bold">バイナリクレート</span>」と「<span class="jinr-d--text-color d--marker1 d--bold">ライブラリクレート</span>」の 2 種類があります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">バイナリクレート（binary crate）</h4>



<p>実行可能なファイル（<code>.exe</code> など）を生成するためのクレートです。プログラムのエントリポイントである <code>main</code> 関数があり、<code>cargo run</code> で実行できるプログラムを作るときに使用します。</p>



<p>バイナリクレートでは、<span class="jinr-d--text-color d--marker1 d--bold"><code>src/main.rs</code></span> が存在し、<code>main()</code> 関数から処理が開始されます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ライブラリクレート（library crate）</h4>



<p>他のコードから再利用される関数や型を提供するためのクレートです。エントリーポイントはなく、公開した API を別のクレートから利用することができます。</p>



<p>ライブラリクレートでは、<span class="jinr-d--text-color d--marker1 d--bold"><code>src/lib.rs</code></span> が存在し、再利用を前提として設計されます。また、後述する crates.io に公開してライブラリを配布することも可能です。</p>



<h3 class="wp-block-heading jinr-heading d--bold">クレートと Cargo プロジェクトの関係性</h3>



<p>Cargo でプロジェクトを作成する際にバイナリクレートか、ライブラリクレートかを切り替えて作成することができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">バイナリクレートの場合 <code>--bin</code></h4>



<p>バイナリクレートは、以下のように <code>cargo new</code> で作成します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo new my_app</pre>



<p><code>cargo new</code> はデフォルトがバイナリクレートとなっています。なお、「<code>--bin</code>」を明示的に指定して実行することも可能です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo new --bin my_app</pre>



<p>バイナリクレートでは、<code>main.rs</code> が作成されます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ライブラリクレートの場合 <code>--lib</code></h4>



<p>ライブラリクレートは、「<code>--lib</code>」を指定して <code>cargo new</code> で作成します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo new --lib my_app</pre>



<p>ライブラリクレートでは、<code>lib.rs</code> が作成されます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">crates.io</h3>



<p><span class="jinr-d--text-color d--marker1 d--bold"><a href="https://crates.io/" target="_blank" rel="noreferrer noopener nofollow">crates.io</a></span> は、Rust の公式パッケージリポジトリです。Rust のライブラリ（クレート）を公開・共有するためのプラットフォームで、Python の PyPI (Python Package Index) や Node.js の npm (Node Package Manager) 等に相当します。</p>



<p>Rust のエコシステムは、crates.io を中心に発展してきており、開発者は必要なライブラリを crates.io で検索し、<code>Cargo.toml</code> に依存のあるクレートとして追加して簡単に利用できます。</p>



<div id="nkhn3-1458857179" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">Rust の依存関係（dependencies）</h2>



<h3 class="wp-block-heading jinr-heading d--bold">依存関係（dependencies）とは</h3>



<p>Rust のプロジェクトでは、自身が開発したコードだけではなく、外部のクレートをプロジェクトに取り込むことで効率的に開発を進めることができます。この外部のクレートを管理する仕組みが Cargo には組み込まれており、<code>Cargo.toml</code> という設定ファイルで制御できます。</p>



<h4 class="wp-block-heading jinr-heading d--bold"><code>Cargo.toml</code> の基本構造</h4>



<p>Cargo で作成したプロジェクトには、必ず <span class="jinr-d--text-color d--marker1 d--bold"><code>Cargo.toml</code></span> というファイルが存在しており、プロジェクト名、バージョン、依存関係などが記載されます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[package]
name = "my_app"
version = "0.1.0"
edition = "2024"

[dependencies]
serde = "1.0.228"
rand = "0.9.2"</pre>



<p><code>[package]</code> セクションには、プロジェクトの名称やバージョン、Rust のエディションなどの情報が記載されます。</p>



<p><code>[dependencies]</code> セクションに書かれているクレートが、Cargo によってダウンロード、ビルドといった管理がされるものです。</p>



<h4 class="wp-block-heading jinr-heading d--bold">[dependencies] の役割</h4>



<p><span class="jinr-d--text-color d--marker1 d--bold"><code>[dependencies]</code></span> セクションは、プロジェクトが利用するクレートを宣言する部分です。キーにクレート名、値が指定するバージョンになります。</p>



<p>例の以下部分では、<code>serde</code> クレートのバージョン <code>1.0.228</code> を使用することを意味します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[dependencies]
serde = "1.0.228"</pre>



<h4 class="wp-block-heading jinr-heading d--bold">セマンティックバージョニング</h4>



<p>Rust では、バージョン番号はセマンティックバージョニング（SemVer）に従っています。セマンティックバージョニングは「<span class="jinr-d--text-color d--marker1 d--bold"><code>MAJOR.MINOR.PATCH</code></span>」の形で、バージョンを構成します。</p>



<ul class="wp-block-list jinr-list">
<li>MAJOR（メジャー）：後方互換性のない変更を行った場合に数字を増やします。大きな機能追加や API の破壊的変更の場合に使用します。</li>



<li>MINOR（マイナー）：後方互換性を保った機能追加を行った場合に数字を増やします。新機能や改善で既存利用者への影響が小さい変更の場合に使用します。</li>



<li>PATCH（パッチ）：後方互換性のあるバグ修正を行った場合に数字を増やします。動作に変更はなく、不具合を修正する場合に使用します。</li>
</ul>



<p>セマンティックバージョニングでは、自動バージョンアップ可能性についても指定ができます。例えば「^1.2.3」のように指定すると、MAJOR が同じであれば、MINOR/PATCH への自動更新は許可するといったことが指定できます。破壊的変更を避けつつ、適度に更新するといったことができるようになっています。</p>



<h3 class="wp-block-heading jinr-heading d--bold">crates.io でのクレートの探し方</h3>



<h4 class="wp-block-heading jinr-heading d--bold">crates.io へのアクセス</h4>



<p>Rust の公式パッケージリポジトリである crates.io には「<a href="https://crates.io/" target="_blank" rel="noreferrer noopener nofollow">https://crates.io/</a>」からアクセスすることができます。検索バーに、クレート名やキーワードを入力することで簡単に目的のクレートを探すことができます。</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="952" height="213" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/12/image.png" alt="crates.io の画面" class="wp-image-1544" srcset="https://rust-tech.nkhn37.net/wp-content/uploads/2025/12/image.png 952w, https://rust-tech.nkhn37.net/wp-content/uploads/2025/12/image-300x67.png 300w, https://rust-tech.nkhn37.net/wp-content/uploads/2025/12/image-768x172.png 768w" sizes="(max-width: 952px) 100vw, 952px" /><figcaption class="wp-element-caption">crates.io の画面<br>（画面構成は変わっている可能性があります）</figcaption></figure>
</div>


<h4 class="wp-block-heading jinr-heading d--bold">クレート情報</h4>



<p>特定のクレートを検索して情報を確認すると以下のような情報を確認できます。</p>



<ul class="wp-block-list jinr-list">
<li>最新バージョン：クレートの現在の安定バージョンが分かります。</li>



<li>ダウンロード数：どれだけダウンロードされているかの人気の指標です。</li>



<li>インストール方法：クレートのインストール方法が分かります。（詳細は後述）</li>



<li>ドキュメント：<code>docs.rs</code> で生成された API ドキュメントへのリンクがあります。</li>



<li>Readme：当該クレートの Readme 情報が表示されます。</li>
</ul>



<p>その他にも、Homepage、GitHub へのリンクや各種メタ情報などを確認可能です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">クレート選びのポイント</h4>



<p>Python では、長年の実績で迷ったらこれというような、事実上一択なライブラリが多くありますが、Rust は比較的新しい言語であることもあり、まだそのようなクレートは少ないです。</p>



<p>ただし、一部の分野ではほぼ共通で使われているようなクレートも存在します。例としては以下のようなものが有名かなと思います。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>分野</th><th>クレート名</th></tr></thead><tbody><tr><td>シリアライズ／デシリアライズ</td><td><code>serde</code></td></tr><tr><td>エラー型</td><td><code>thiserror</code>、<code>anyhow</code></td></tr><tr><td>ログ基盤</td><td><code>log</code></td></tr><tr><td>日付時刻</td><td><code>chrono</code></td></tr><tr><td>CLI</td><td><code>clap</code></td></tr><tr><td>非同期処理</td><td><code>tokio</code></td></tr><tr><td>HTTP クライアント</td><td><code>reqwest</code></td></tr><tr><td>Web フレームワーク</td><td><code>axum</code>、<code>actix-web</code></td></tr></tbody></table></figure>



<p>上記は有名どころのクレートであり、多くのプロジェクトでも使用されているため安心して利用できます。</p>



<p>他にもたくさんのクレートがありますので、使えるクレートはどんどん試していただければと思います。外部クレートを選ぶ際は、以下のような点を確認することがおすすめです。</p>



<ul class="wp-block-list jinr-list">
<li>最終更新日が新しいか</li>



<li>ドキュメントが整備されているか</li>



<li>ダウンロード数が多いか</li>



<li>依存関係が過剰に多くないか</li>



<li>GitHub のアクティビティなどメンテナンスはどの程度されているか</li>
</ul>



<h3 class="wp-block-heading jinr-heading d--bold">依存クレートの追加と管理</h3>



<p>依存関係は <code>Cargo.toml</code> の <code>[dependencies]</code> に直接記述することもできますが、<span class="jinr-d--text-color d--marker1 d--bold"><code>cargo</code></span> コマンドによる管理も可能です。各種コマンドについて紹介します。</p>



<h4 class="wp-block-heading jinr-heading d--bold">cargo コマンドによるクレートの追加と管理</h4>



<p>依存性の管理では、<code>cargo</code> コマンドを以下のように実行します。シリアライズ／デシリアライズのためのクレートである <code>serde</code> を例に紹介します。</p>



<h5 class="wp-block-heading jinr-heading d--bold">クレートの追加</h5>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo add serde</pre>



<h5 class="wp-block-heading jinr-heading d--bold">バージョンを指定して追加</h5>



<p>バージョンを指定する場合は、クレート名の後に <code>@</code> でバージョン番号を指定します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo add serde@1.0.228</pre>



<h5 class="wp-block-heading jinr-heading d--bold">クレートの依存関係の更新</h5>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo update</pre>



<h5 class="wp-block-heading jinr-heading d--bold">クレートの依存ツリーの確認</h5>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo tree</pre>



<p>上記のようなコマンドを使うことで、プロジェクトの依存関係を管理、構造の確認といったことが容易にできます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">features の指定</h4>



<p>クレートには、Feature と呼ばれる追加機能がある場合があります。Feature を有効化するには、以下のように <code>cargo add</code> にオプションとして追加できます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cargo add serde --features derive</pre>



<p>また、<code>Cargo.toml</code>  で以下のように <code>features</code> を指定しても構いません。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">serde = { version = "1.0.228", features = ["derive"] }</pre>



<p>上記では、<code>serde</code> クレートで <code>derive</code> マクロが使えるように <code>features</code> を指定しています。どのような <code>features</code> があるかどうかは、各クレートのドキュメントなどを確認してください。</p>



<p><code>features</code> を使用することで、必要な機能だけを有効化して不要な依存関係を避けることができます。Rust のクレート設計では、この <code>features</code> はよく使用されています。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust における<span class="jinr-d--text-color d--marker1 d--bold">クレート</span>と<span class="jinr-d--text-color d--marker1 d--bold">依存関係の管理</span>について解説しました。</p>



<p>Rust におけるクレート（crate）とは、コンパイル可能な最小単位のコードのまとまりのことで、バイナリクレートとライブラリクレートといった種類があります。また、クレートには依存関係（dependencies）というものがあり、Cargo を用いて作成したプロジェクトでは依存関係を柔軟に管理することができます。</p>



<p><a href="https://crates.io/" target="_blank" rel="noreferrer noopener nofollow">crates.io</a> には、多くの便利なクレートが公開されて利用できるようになっています。ぜひ、色々なクレートを使用して効率的に Rust の開発をしていってください。</p>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section>


<p></p>
<div id="nkhn3-2044177335" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-crates-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】ファイル入出力の基本を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-file-input-output/</link>
					<comments>https://rust-tech.nkhn37.net/rust-file-input-output/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 04 Oct 2025 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[bufread]]></category>
		<category><![CDATA[openoptions]]></category>
		<category><![CDATA[read]]></category>
		<category><![CDATA[write]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=1368</guid>

					<description><![CDATA[Rust のファイル入出力の基本について解説します。 Rust の入出力 プログラミング言語において、ファイル入出力は非常に基本的で重要な処理です。Rust の入出力は、Read、BufRead、Write というトレイ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Rust の<span class="jinr-d--text-color d--marker1 d--bold">ファイル入出力の基本</span>について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">Rust の入出力</h2>



<p>プログラミング言語において、ファイル入出力は非常に基本的で重要な処理です。Rust の入出力は、<code><span class="jinr-d--text-color d--marker1 d--bold">Read</span></code>、<code><span class="jinr-d--text-color d--marker1 d--bold">BufRead</span></code>、<code><span class="jinr-d--text-color d--marker1 d--bold">Write</span></code> というトレイトを中心に構築されています。入出力という広い観点で見ると「ファイル」「標準入出力」「ネットワーク」など様々な対象がありますが、Rust では、いずれもこれらのトレイトを通じて扱うことができます。</p>



<p>この記事では、トレイトの細かなところまでは踏み込みませんが、テキストファイルの入出力を通じて Rust でのファイル入出力の基本を紹介します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p>トレイトの基本については以下を参考にしてください。</p>



<p><a href="https://rust-tech.nkhn37.net/rust-trait-basic/" target="_blank" rel="noreferrer noopener">トレイトの基本を分かりやすく解説</a></p>
</div>
		</div></section>



<div id="nkhn3-2351954404" class="nkhn3- nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="4670569211"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div><h2 class="wp-block-heading jinr-heading d--bold">テキストファイルの入出力</h2>



<h3 class="wp-block-heading jinr-heading d--bold">テキストファイルの読み込み</h3>



<h4 class="wp-block-heading jinr-heading d--bold">ファイルを開いて全てのテキストを読み込む <code>read_to_string</code></h4>



<p>テキストファイルを開いて内容を読み込むには、<code><span class="jinr-d--text-color d--marker1 d--bold">read_to_string</span></code> メソッドを使用します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="6" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::fs;
use std::io::{self};

fn read_file(filepath: &amp;str) -> io::Result&lt;()> {
    // ファイルパスのデータを String 型で取得する
    let contents = fs::read_to_string(filepath)?;
    // 読み込んだ文字列を表示する
    println!("{}", contents);

    Ok(())
}

fn main() {
    // ファイルパスは任意のパスに変更してください
    let filepath = r"D:\RustProject\rust-tech-sample-source\rust-basic\file_input_output\examples\input_example.txt";

    // ファイル読み込み関数を呼び出し、エラーが発生した場合はエラーを表示する
    if let Err(e) = read_file(filepath) {
        println!("Error: {}", e);
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】※ input_example.txt の内容
Rust Programming
ファイル入出力の基本
テキストファイルの入出力</pre>



<p>「<code>use std::fs;</code>」とすることで、標準ライブラリ <code>std</code> 内の <code>fs</code> モジュールを使用します。<code>read_to_string</code> は <code>fs</code> モジュール内の関数で、ファイルパスを渡すことで、ファイルの中身を <code>String</code> 型で読み込むことができます。</p>



<p>この <code>read_to_string</code> 関数の返却値の型は、<code>io::Result&lt;String&gt;</code> 型になります。上記例の <code>read_file</code> 関数では、返却値を <code>io::Result&lt;()&gt;</code> として、? 演算子によりエラーが発生した場合や呼び出し元に移譲しています。</p>



<p>エラーの場合は、呼び出し元の <code>main</code> 関数内で <code>if let</code> により <code>Err</code> を補足してエラーを表示するようにしています。より丁寧にエラー処理をする場合は、<code>match</code> による処理ももちろん可能です。エラー処理の基本が分からない方は「<a href="https://rust-tech.nkhn37.net/rust-error-handling-basic/" target="_blank" rel="noreferrer noopener">エラー処理の基本を分かりやすく解説</a>」も参考にしてください。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ファイルを開いてから読み込む</h4>



<p><code>read_to_string</code> 関数は、上記のようにファイルパスを指定して簡単にテキストファイルを読み込むことができますが、以下の例のように <code>fs::File::open</code> によりファイルを開いてから、読込先の <code>String</code> を渡して読み込むことも可能です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="2-3, 6" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::fs;
use std::io::{self, Read};

fn read_file(filepath: &amp;str) -> io::Result&lt;()> {
    let mut file = fs::File::open(filepath)?;
    let mut contents = String::new();

    // ファイルの内容を読み込み
    file.read_to_string(&amp;mut contents)?;
    // 読み込んだ文字列を表示する
    println!("{contents}");

    Ok(())
}</pre>



<p>この時、<code><span class="jinr-d--text-color d--marker1 d--bold">Read</span></code> トレイトを <code>use</code> 指定する必要がある点に注意してください。先ほどまで使用していた <code>fs::read_to_string</code> は <code>fs</code> モジュール内に定義された関数でした。一方で、上記例は <code>File</code> 型にトレイトのメソッドとして定義した <code>read_to_string</code> を使用しているため、似ているように見えて全くの別物です。</p>



<p>トレイトで定義されるメソッドを使用する際には、<code>use</code> でトレイトを読み込む必要があるため、上記の例では <code>Read</code> トレイトの読み込みが必要となるわけです。</p>



<h4 class="wp-block-heading jinr-heading d--bold">1行ずつ読み込む</h4>



<p>ファイルを 1行ずつ読み込む場合には、<code><span class="jinr-d--text-color d--marker1 d--bold">BufReader</span></code> により順次処理をすることが可能です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="2, 9,11" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::fs::File;
use std::io::{self, BufRead, BufReader};

fn read_lines(filepath: &amp;str) -> io::Result&lt;()> {
    let file = File::open(filepath)?;
    let reader = BufReader::new(file);

    // ファイルを1行ずつ読み込む
    for line in reader.lines() {
        // line は Result&lt;String, Error> なので値を取り出す
        let line = line?;
        println!("{} :文字数({})", line, line.chars().count());
    }

    Ok(())
}

fn main() {
    // ファイルパスは任意のパスに変更してください
    let filepath = r"D:\RustProject\rust-tech-sample-source\rust-basic\file_input_output\examples\input_example.txt";

    // ファイル読み込み関数を呼び出し、エラーが発生した場合はエラーを表示する
    if let Err(e) = read_lines(filepath) {
        println!("Error: {}", e);
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果】
Rust Programming :文字数(16)
ファイル入出力の基本 :文字数(10)
テキストファイルの入出力 :文字数(12)</pre>



<p>上記例では、まず <code>File::open</code> によりファイルを開き、<code>BufReader</code> の <code>new</code> 関数に渡すことで <code>reader</code> を生成します。<code>reader.lines()</code> により各行のデータを順に取得することができるため、<code>for</code> 文で <code>line</code> に値を入れつつ 1行ずつ処理をすることが可能です。</p>



<p>なお、<code><span class="jinr-d--text-color d--marker1 d--bold">BufRead</span></code> トレイトと <code><span class="jinr-d--text-color d--marker1 d--bold">BufReader</span></code> 型を use 指定する必要があるので注意してください。</p>



<p>取り出される <code>line</code> は、<code>Result&lt;String, Error&gt;</code> 型であるため、<code>?</code> 演算子により値を取り出してから使用しています。このようにすることで、1行ずつファイルを読み込み処理をすることができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">テキストファイルの書き込み</h3>



<p>入力は主に <code>read_to_string</code> などのメソッドを用いて行いましたが、書き込みでは <code><span class="jinr-d--text-color d--marker1 d--bold">write!</span></code> マクロを使用します。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ファイルを作成して書き込む</h4>



<p>ファイルの書き込みを行う場合には、<code><span class="jinr-d--text-color d--marker1 d--bold">OpenOptions</span></code> 型を使用します。この型では、「<code>.</code>」でメソッドを連結することでファイルを開く際のオプションを指定することが可能になっています。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="2, 6-9,12" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::fs::OpenOptions;
use std::io::{self, Write};

fn write_new_file(filepath: &amp;str, text: &amp;str) -> io::Result&lt;()> {
    // ファイルを作成して開く
    let mut file = OpenOptions::new()
        .write(true)
        .create_new(true) // ファイルが存在するとエラー
        .open(filepath)?;

    // 文字列を書き込む
    writeln!(file, "{text}")?;

    Ok(())
}

fn main() {
    // ファイルパスは任意のパスに変更してください
    let filepath = r"D:\RustProject\rust-tech-sample-source\rust-basic\file_input_output\examples\output_example.txt";

    // 書き込み文字列を準備
    let write_str = "Rust Programming\nファイル入出力の基本\nテキストファイルの入出力";

    // ファイル書き込み関数を呼び出し、エラーが発生した場合はエラーを表示する
    if let Err(e) = write_new_file(filepath, write_str) {
        println!("Error: {e}");
    }
}</pre>



<p>ファイルを書き込む際には「<code><span class="jinr-d--text-color d--marker1 d--bold">.write(true).create_new(true).open(filepath)</span></code>」とすることで、指定したファイルパスでファイルを作成して、書き込みモードで開くことができます。この時ファイルが存在する場合は、エラーとなります。</p>



<p>ファイルを書き込む場合には、<code>writeln!</code> マクロを使用します。このマクロは、<code>println!</code> マクロとほとんど同じですが、第1引数に <code>File</code> 型のインスタンスを指定していることとが異なります。なお、改行を含まないように出力したい場合は <code>write!</code> マクロで対応可能です。</p>



<p>また、返却値として <code>Result</code> 型が返ってくる点も <code>println!</code> マクロとは異なるためエラー処理が必要です。上記例では <code>?</code> 演算子により処理をしています。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ファイルを開いて追記する</h4>



<p>ログファイルの出力など、ファイルを追記モードで開いて末尾に文字列を追記したくなることが良くあります。この場合は、以下のように「<code><span class="jinr-d--text-color d--marker1 d--bold">.append(true)</span></code>」とすることで対応可能です。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="7" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::fs::OpenOptions;
use std::io::{self, Write};

fn write_append_file(filepath: &amp;str, text: &amp;str) -> io::Result&lt;()> {
    // ファイルを追記モードで開く
    let mut file = OpenOptions::new()
        .append(true) // ファイルが存在しない場合、エラー
        .open(filepath)?;

    // 文字列を書き込む
    writeln!(file, "{text}")?;

    Ok(())
}

fn main() {
    let filepath = r"D:\RustProject\rust-tech-sample-source\rust-basic\file_input_output\examples\output_example.txt";

    // 追記する文字列を準備
    let append_str = "Rust 文字列の追記";

    // ファイル書き込み関数を呼び出し、エラーが発生した場合はエラーを表示する
    if let Err(e) = write_append_file(filepath, append_str) {
        println!("Error: {e}");
    }
}</pre>



<p>この場合、ファイルが存在しない場合はエラーとなるので注意してください。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p>Rust の<span class="jinr-d--text-color d--marker1 d--bold">ファイル入出力の基本</span>について解説しました。この記事では、テキストファイルの読み込み・書き込みを中心に紹介しています。</p>



<p>ファイル入出力は、どのようなプログラミング言語においても基本になります。Rust の I/O を理解することで、より安全でパフォーマンスの高いプログラムが書けるようになりましょう。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p>上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/file-input-output" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://rust-tech.nkhn37.net/rust-programming-basics/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://rust-tech.nkhn37.net/wp-content/uploads/2025/08/77e7c51961993fb9cb96c02a2311436d-320x180.jpg" alt="Rust プログラミング入門" /></div><div class="a--blogcard-title d--bold">Rust プログラミング入門</div></a></section><div id="nkhn3-1822341777" class="nkhn3-multiplex nkhn3-entity-placement" style="margin-left: auto;margin-right: auto;text-align: center;"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9478001176347002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-9478001176347002"
     data-ad-slot="8958649655"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>]]></content:encoded>
					
					<wfw:commentRss>https://rust-tech.nkhn37.net/rust-file-input-output/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Disk: Enhanced  を使用したページ キャッシュ

Served from: rust-tech.nkhn37.net @ 2026-04-18 14:34:44 by W3 Total Cache
-->