<?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/tag/trait/feed/" rel="self" type="application/rss+xml" />
	<link>https://rust-tech.nkhn37.net</link>
	<description>Rustプログラミング学習サイト</description>
	<lastBuildDate>Tue, 31 Mar 2026 20:32:59 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</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）の基本を分かりやすく解説</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 class="wp-block-paragraph">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 class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">イテレータ（Iterator）</span>は、値の列を生成する値で、要素を順番に取り出すことができる仕組みです。Rust では、文字列や <code>Vec</code> などから要素を取り出して処理するイテレータが用意されています。他にも、様々な場面でイテレータの仕組みが利用されています。</p>



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



<p class="wp-block-paragraph">この記事では、<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 class="wp-block-paragraph">この記事では、トレイトに関する基本知識が必要です。トレイトについては「<a href="https://rust-tech.nkhn37.net/rust-trait-basic/" target="_blank" rel="noreferrer noopener">トレイトの基本を分かりやすく解説</a>」を参考にしてください。</p>
</div>
		</div></section>



<div id="nkhn3-474645310" 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 class="wp-block-paragraph">イテレータを実現する中心的なトレイトは、<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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><code>iter</code> メソッドは、対象のイテレータを取得します。（<code>iter</code> については後ほど説明します。）</p>



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



<p class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph">以下の例を見てみましょう。</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 class="wp-block-paragraph">このように、<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 class="wp-block-paragraph">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 class="wp-block-paragraph"><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 class="wp-block-paragraph">これは、内部的には、概ね次のような処理が行われていると考えることができます。<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 class="wp-block-paragraph">つまり、「<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 class="wp-block-paragraph">ここで示したコードは概念的な説明であり、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 class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph">以下の例で見てみましょう。</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 class="wp-block-paragraph">例えば、<code>iter</code> を使用すると要素への不変参照を順番に取り出すことができます。不変参照なので、値を変更しようとするとコンパイルエラーとなります。一方で、<code>iter_mut</code> を使用すると要素への可変参照を取得できるため、要素の値を書き換えることができます。</p>



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



<p class="wp-block-paragraph">多くのコレクションでは以下のような対応関係があります。</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 class="wp-block-paragraph">つまり、<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 class="wp-block-paragraph">これらは、Rust の標準ライブラリにおいて、コレクションがイテレータを生成するための便利なメソッドとして提供しているものです。そのため、必ずしも上記対応が保証されているわけではありませんので注意してください。</p>



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



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



<p class="wp-block-paragraph">イテレータの中心となるのが、<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 class="wp-block-paragraph">イテレータは、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 class="wp-block-paragraph">上記で紹介しているソースコードについては&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-787061933" 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 class="wp-block-paragraph">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 class="wp-block-paragraph">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 class="wp-block-paragraph">この記事では、基本からは一段深く、<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 class="wp-block-paragraph">以降の内容の理解には型やトレイトの基本的な知識が必要です。基本的な内容については、以下を参考にしてください。</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-806405928" 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 class="wp-block-paragraph">まずは、クロージャーの本質について確認してみましょう。結論から述べると<span class="jinr-d--text-color d--marker1 d--bold">クロージャは、コンパイラが生成する固有の型</span>です。</p>



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



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



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



<p class="wp-block-paragraph">では、このクロージャが関数として扱えるかを試してみましょう。以下の <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 class="wp-block-paragraph">例の <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 class="wp-block-paragraph">通常関数の <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 class="wp-block-paragraph">理由はシンプルで、クロージャーの型は「<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 class="wp-block-paragraph">上記で、通常関数とクロージャは型が異なることが分かりました。しかし、関数にクロージャを渡して実行したいケースは非常に多くあります。関数とクロージャーを同じように扱う方法はないのでしょうか？もちろんあります。ポイントとなるのが <span class="jinr-d--text-color d--marker1 d--bold"><code>Fn</code> トレイト</span>です。</p>



<p class="wp-block-paragraph">次の例のようにトレイト境界を用いた <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 class="wp-block-paragraph">このようにすることで「通常の関数」と「クロージャ」をどちらも同じように扱うことができます。これは、通常の関数もクロージャも、<code>Fn</code> トレイトを通じて扱うことができるためです。</p>



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



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



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



<p class="wp-block-paragraph">クロージャの基本記事「<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 class="wp-block-paragraph"><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 class="wp-block-paragraph">例では、<code>x</code> をクロージャの中で参照しているだけで変更していません。そのため、このクロージャは <code>Fn</code> トレイトを実装します。<code>Fn</code> のクロージャは、状態を変更しないため何度でも安全に呼び出すことができます。</p>



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



<p class="wp-block-paragraph"><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 class="wp-block-paragraph">例では、クロージャの中で <code>count</code> を変更しています。そのため、このクロージャは <code>FnMut</code> トレイトを実装します。</p>



<p class="wp-block-paragraph"><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 class="wp-block-paragraph"><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 class="wp-block-paragraph">例では、<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 class="wp-block-paragraph"><strong>【<code>move</code> について】</strong></p>



<p class="wp-block-paragraph">例では、明示的に <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 class="wp-block-paragraph">上記で紹介したトレイトは、次のような関係になっています。</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 fetchpriority="high" 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 class="wp-block-paragraph">上記図は「<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 class="wp-block-paragraph">記事の前半で <code>Fn</code> をトレイト境界に持つ関数の例を紹介しましたが、この <code>call_function</code> は、<code>FnMut</code> のクロージャを受け取ることができません。一方で、<code>FnMut</code> をトレイト境界に持つ関数は、<code>Fn</code> トレイトのクロージャを受け取ることが可能となります。</p>



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



<div id="nkhn3-3335948216" 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 class="wp-block-paragraph">Rust における<span class="jinr-d--text-color d--marker1 d--bold">クロージャ（Closure）の型とトレイト（<code>Fn</code> / <code>FnMut</code> / <code>FnOnce</code>）</span>について解説しました。</p>



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



<p class="wp-block-paragraph">また、クロージャは、キャプチャする外部変数の扱い方に応じて、<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 class="wp-block-paragraph">上記で紹介しているソースコードについては&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-3670054535" 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-trait-basic/</link>
					<comments>https://rust-tech.nkhn37.net/rust-trait-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 22 Aug 2025 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[derive]]></category>
		<category><![CDATA[デフォルト実装]]></category>
		<category><![CDATA[トレイト]]></category>
		<category><![CDATA[トレイト境界]]></category>
		<guid isPermaLink="false">https://rust-tech.nkhn37.net/?p=397</guid>

					<description><![CDATA[Rust のトレイトの基本について初心者にも分かりやすく解説します。 Rust のトレイト トレイトとは Rust におけるトレイト（trait）は、型に共通の振る舞いを定義する仕組みです。Haskell の型クラスに非 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Rust の<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 class="wp-block-paragraph">Rust における<span class="jinr-d--text-color d--marker1 d--bold">トレイト（trait）</span>は、型に共通の振る舞いを定義する仕組みです。Haskell の型クラスに非常によく似ており、Java 等のオブジェクト指向言語ではインターフェースに近いものとなっています。</p>



<p class="wp-block-paragraph">オブジェクト指向では、振る舞いをクラスに内包されたメソッドで定義しますが、Rust のトレイトではデータ構造（<code>struct</code> や <code>enum</code>）と振る舞い（<code>trait</code>）を分離する点で違いがあります。型そのものには基本的にはデータ構造しかなく、振る舞いはトレイトを後から付与して実装するという考え方です。</p>



<p class="wp-block-paragraph">トレイトを使用することで、例えば「コンソールに出力ができる」「数値計算ができる」のような共通の振る舞いを定義し、型がその振る舞いをどのように実現するのかを実装できるようになります。</p>



<p class="wp-block-paragraph">この記事では、トレイトの基本について分かりやすく解説します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">トレイトの定義と実装の基本</h3>



<p class="wp-block-paragraph">トレイトの説明をする際によく利用される図形を用いた例でトレイトを説明します。例えば、図形には、<code>Circle</code>（円）、<code>Rectangle</code>（矩形）などを色々と考えることができます。これらの図形に共通的なことを考えてみると「面積を計算できる」ということが挙げられます。</p>



<p class="wp-block-paragraph">領域に関するトレイトを <code>Area</code> トレイトとして、面積を計算する振る舞いを <code>area</code> メソッドとして実装してみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="3-7,12-17,22-27" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::f64::consts::PI;

// 領域に関するトレイト
trait Area {
    // 面積を計算するメソッド
    fn area(&amp;self) -> f64;
}

// 円の構造体の定義
struct Circle { radius: f64 }

// トレイトの実装 (Circle)
impl Area for Circle {
    fn area(&amp;self) -> f64 {
        PI * self.radius * self.radius
    }
}

// 矩形の構造体の定義
struct Rectangle { width: f64, height: f64 }

// トレイトの実装 (Rectangle)
impl Area for Rectangle {
    fn area(&amp;self) -> f64 {
        self.width * self.height
    }
}

fn main() {
    let circle = Circle{
        radius: 5.0
    };
    let circle_area = circle.area();
    println!("Circle(radius={:.2}), Area: {:.2}", circle.radius, circle_area);

    let rect = Rectangle{
        width: 5.0,
        height: 10.5,
    };
    let rect_area = rect.area();
    println!("Rectangle(width={:.2}, height={:.2}), Area: {:.2}", rect.width, rect.height, rect_area);
}</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="">【実行結果】
Circle(radius=5.00), Area: 78.54
Rectangle(width=5.00, height=10.50), Area: 52.50</pre>



<p class="wp-block-paragraph"><code>Area</code> トレイトは「<code>trait Area {}</code>」のように定義し、内部にはそのトレイトが持つべきメソッドの定義を「<code>fn area(&amp;self) -&gt; f64;</code>」のように型注釈を含めて記載します。なお、今回は <code>area</code> というメソッドのみですが <code>Area</code> という領域に関する振る舞いを他に定義したい場合は、複数のメソッドを定義可能です。</p>



<p class="wp-block-paragraph">今回用意した円（<code>Circle</code>）や矩形（<code>Rectangle</code>）という型に <code>Area</code> トレイトを実装するには「<code>impl Area for 型名 {}</code>」のように定義し、内部では先ほど型注釈のみで実装はしていなかった <code>area</code> メソッドの具体的な実装を記載します。</p>



<p class="wp-block-paragraph">なお、トレイトでは、<span class="jinr-d--text-color d--marker1 d--bold">トレイトが定義するメソッドを実装することを強制</span>します。厳密には、後ほど説明するデフォルト実装がないメソッドの実装が必須です。</p>



<p class="wp-block-paragraph">そのため、「<code>impl Area for 型名 {}</code>」と宣言したら、<code>area</code> メソッドの実装は必須です。もし他にもメソッドがトレイトで定義されていたら全てのメソッドを実装する必要があります。これにより、あるトレイトを持つ型は、そのトレイトで定義されているメソッドが確実に実装されているものとして安心して型を使用することができます。</p>



<p class="wp-block-paragraph"><code>main</code> 関数では、各型をインスタンス化していますが、それぞれ <code>Area</code> トレイトを実装しているので <code>area</code> メソッドを使用して面積を計算できていることが分かります。他の形状の型が出てきた場合にも、それぞれに関する Area トレイトの実装を追加していくことができます。</p>



<h3 class="wp-block-heading jinr-heading d--bold">トレイトのデフォルト実装</h3>



<p class="wp-block-paragraph">トレイトには「<span class="jinr-d--text-color d--marker1 d--bold">デフォルト実装</span>」として基本となる実装を定義しておくことができます。デフォルト実装とは、もし型側で実装が行われなかった場合に使用される実装のことです。</p>



<p class="wp-block-paragraph"><code>Area</code> トレイトに <code>describe</code> という面積を表示するメソッドを追加してデフォルト実装の例を見てみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="7-10,21,32-35" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::f64::consts::PI;

// 領域に関するトレイト
trait Area {
    // 面積を計算するメソッド
    fn area(&amp;self) -> f64;
    // デフォルト実装
    fn describe(&amp;self) {
        println!("Area: {:.2}", self.area())
    }
}

// 円の構造体の定義
struct Circle { radius: f64 }

// トレイトの実装 (Circle)
impl Area for Circle {
    fn area(&amp;self) -> f64 {
        PI * self.radius * self.radius
    }
    // describe はデフォルト実装を使用
}

// 矩形の構造体の定義
struct Rectangle { width: f64, height: f64 }

// トレイトの実装 (Rectangle)
impl Area for Rectangle {
    fn area(&amp;self) -> f64 {
        self.width * self.height
    }
    // describeのデフォルト実装をオーバーライドしている
    fn describe(&amp;self) {
        println!("Rectangle(width={:.2}, height={:.2}), Area: {:.2}", self.width, self.height, self.area());
    }
}

fn main() {
    let circle = Circle{
        radius: 5.0
    };
    let _circle_area = circle.area();
    circle.describe();

    let rect = Rectangle{
        width: 5.0,
        height: 10.5,
    };
    let _rect_area = rect.area();
    rect.describe();
}
</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="">【実行結果】
Area: 78.54
Rectangle(width=5.00, height=10.50), Area: 52.50</pre>



<p class="wp-block-paragraph">上記例では <code>describe</code> により <code>area</code> を呼び出した結果の面積の値を <code>println</code> で表示するようにしています。これにより、型で <code>describe</code> を実装していなくても「<code>Area: xx.xx</code>」と表示されるようになります。これがデフォルト実装です。</p>



<p class="wp-block-paragraph"><code>Circle</code> 型に対する <code>Area</code> トレイトの実装には、<code>describe</code> に関する定義をしていませんが <code>main</code> 関数内では問題なく <code>describe</code> が使用できています。なお、デフォルト実装を用意していないメソッドを実装していない場合は「<code>missing describe in implementation</code>」というコンパイルエラーとなります。これは、トレイトが定義するメソッドの実装が強制されているためです。</p>



<p class="wp-block-paragraph">一方で、<code>Rectangle</code> 型については<code>describe</code> メソッドを個別に定義してオーバーライドすることで、デフォルト実装とは異なる表示ができていることが分かります。</p>



<h3 class="wp-block-heading jinr-heading d--bold">トレイトの自動実装 <code>#[derive()]</code></h3>



<h4 class="wp-block-heading jinr-heading d--bold">トレイトの自動実装の使い方</h4>



<p class="wp-block-paragraph">Rust のトレイトでは、標準トレイトが用意されており、作成した型に対して <code><span class="jinr-d--text-color d--marker1 d--bold">#[derive()]</span></code> を使用することで、トレイトを自動で実装することができます。</p>



<p class="wp-block-paragraph">代表的な例としては、作成した型の情報を <code>println</code> で表示したい場合です。通常は、<code>構造体名.フィールド名</code> というようにアクセスして表示する必要がありますが、標準トレイトに <code>Debug</code> というトレイトが用意されており、以下の例のように <code>derive</code> することで <code>println</code> の <code>{:?}</code> で型の値を表示することができるようになります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="2,6" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 円の構造体の定義
#[derive(Debug)]
struct Circle { radius: f64 }

// 矩形の構造体の定義
#[derive(Debug)]
struct Rectangle { width: f64, height: f64 }

fn main() {
    let circle = Circle{
        radius: 5.0
    };
    println!("{:?}", circle);

    let rect = Rectangle{
        width: 5.0,
        height: 10.5,
    };
    println!("{:?}", rect);
}</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="">【実行結果】
Circle { radius: 5.0 }
Rectangle { width: 5.0, height: 10.5 }</pre>



<p class="wp-block-paragraph"><code>Debug</code> トレイトの自動実装を行うためには、型（<code>struct</code>）定義の上に「<code>#[derive(Debug)]</code>」というように記載します。他にも複数の標準トレイトを自動実装したい場合には「<code>,</code>」で列挙することが可能です。</p>



<p class="wp-block-paragraph">これにより、<code>main</code> 関数内での <code>println</code> で <code>{:?}</code> とした部分に型のインスタンスを指定すると「<code>Circle { radius: 5.0 }</code>」や「<code>Rectangle { width: 5.0, height: 10.5 }</code>」といったように型名とフィールドの値を表現した形で表示することが可能になります。</p>



<h4 class="wp-block-heading jinr-heading d--bold">トレイト自動実装が使える標準ライブラリのトレイト</h4>



<p class="wp-block-paragraph">Rust の<a href="https://doc.rust-lang.org/std/all.html#traits" target="_blank" rel="noreferrer noopener">標準ライブラリ（std）のドキュメントの Traits</a>で、標準ライブラリで定義されているトレイトの一覧を確認できます。各 Traits の参照先ドキュメントで、<code>derive</code> できるかどうかを確認することができます。代表的な <code>derive</code> できる標準トレイトには以下があります。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>標準トレイト</th><th>概要</th></tr></thead><tbody><tr><td><code>Clone</code><br><code>#[derive(Clone)</code></td><td>値の複製するトレイト。<code>clone()</code> を提供する。全てのフィールドが <code>Clone</code> なら <code>derive</code> 可能。</td></tr><tr><td><code>Copy</code><br><code>#[derive(Copy, Clone)]</code></td><td>ビット単位でコピー可能にするトレイト。全てのフィールドが <code>Copy</code> のときのみ <code>derive</code> 可能。<code>Copy</code> を実装する型は必ず <code>Clone</code> の実装が必要。</td></tr><tr><td><code>Debug</code><br><code>#[derive(Debug)]</code></td><td>デバッグ用の出力を可能にするトレイト。<code>{:?}</code>  フォーマットで使用でき、ログや開発中の確認に使用する。</td></tr><tr><td><code>Default</code><br><code>#[derive(Default)]</code></td><td>型のデフォルト値を生成する <code>default()</code> を提供する。全てのフィールドが <code>Default</code> なら <code>derive</code> 可能。</td></tr><tr><td><code>PartialEq</code><br><code>#[derive(PartialEq)]</code></td><td><code>==</code> や <code>!=</code> で比較できるようにする。</td></tr><tr><td><code>Eq</code><br><code>#[derive(Eq, PartialEq)]</code></td><td>数学的に厳密な等価関係を持ち、反射律、対称律、推移律を満たす。<code>f64</code> などの浮動小数点は、<code>NaN == NaN</code> が <code>false</code> で反射律を満たさないため <code>Eq</code> ではない。<code>Eq</code> を実装する型は必ず <code>PartialEq</code> でもある。</td></tr><tr><td><code>PartialOrd</code><br><code>#[derive(PartialOrd)]</code></td><td>大小比較「<code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code>」ができるようにする。</td></tr><tr><td><code>Ord</code><br><code>#[derive(Ord, PartialOrd)]</code></td><td>全ての要素間で大小が決まる（全順序）。<code>f64</code> などの浮動小数点は、<code>NaN</code> を含むと比較が成立しないため <code>Ord</code> ではない。<code>Ord</code> を実装する型は必ず <code>PartialOrd</code> でもある。</td></tr><tr><td><code>Hash</code><br><code>#[derive(Hash, Eq, PartialEq)]</code></td><td>値をハッシュ可能にする。<code>HashMap</code> や <code>HashSet</code> のキーとして使えるようになる。<code>Eq</code> と整合し、<code>a == b</code> であれば、<code>hash(a) == hash(b)</code> である必要があります。</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">「<code>Copy</code> を実装する型は <code>Clone</code> も実装している必要がある」といったようなルールがある型については「<code>#[derive(Copy, Clone)]</code>」のようにセットで使用する必要があるので注意が必要です。列挙する場合の順序は関係ありません。</p>



<p class="wp-block-paragraph">また、<code>Debug</code> が <code>derive</code> できるので <code>std::fmt::Display</code> でもできそうな気がしますが、<code>Display</code> トレイトは使用できません。<code>Debug</code> が開発者がとりあえず読める形で出せればよいという性質であるのに対して、<code>Display</code> はユーザー向けの整形出力で、状況に応じた文言やフォーマットを設計する必要があるため、自動実装の対象に含まれていません。</p>



<p class="wp-block-paragraph">このように標準トレイトでも必ずしも自動実装が使えるわけではないことは覚えておいてください。また、自動実装で求めている機能を提供できるかは十分に確認してください。もし、求めている内容ではない場合には、自分で実装をしてオーバーライドする必要があります。</p>



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



<p class="wp-block-paragraph">トレイトは、共通の振る舞いを型に付与できるものでした。ジェネリックな関数を作成する際には、引数の型があるトレイトを実装している型のみを許容するように制限することができます。このような制約のことを「<span class="jinr-d--text-color d--marker1 d--bold">トレイト境界（Trait Bounds）</span>」と言います。</p>



<p class="wp-block-paragraph">例えば、以下のように面積を表示するような関数 <code>show_area</code> を定義してみます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="2, 33" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use std::f64::consts::PI;
use std::fmt::Debug;

// 領域に関するトレイト
trait Area {
    // 面積を計算するメソッド
    fn area(&amp;self) -> f64;
}

// 円の構造体の定義
#[derive(Debug)]
struct Circle { radius: f64 }

// トレイトの実装 (Circle)
impl Area for Circle {
    fn area(&amp;self) -> f64 {
        PI * self.radius * self.radius
    }
}

// 矩形の構造体の定義
#[derive(Debug)]
struct Rectangle { width: f64, height: f64 }

// トレイトの実装 (Rectangle)
impl Area for Rectangle {
    fn area(&amp;self) -> f64 {
        self.width * self.height
    }
}

// 面積を表示する関数 (トレイト境界)
fn show_area&lt;T: Area + Debug>(shape: &amp;T) {
    println!("{:?}, Area: {:.2}", shape, shape.area());
}

fn main() {
    let circle = Circle{
        radius: 5.0
    };
    show_area(&amp;circle);

    let rect = Rectangle{
        width: 5.0,
        height: 10.5,
    };
    show_area(&amp;rect);
}
</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="">【実行結果】
Circle { radius: 5.0 }, Area: 78.54
Rectangle { width: 5.0, height: 10.5 }, Area: 52.50</pre>



<p class="wp-block-paragraph"><code>show_area</code> では、型の情報を表示し、面積を計算した結果を表示するので <code>Debug</code> トレイトと <code>Area</code> トレイトを持った型を引数に受け取りたくなります。</p>



<p class="wp-block-paragraph">このような場合でトレイト境界を指定するには、関数名の後ろに <code>&lt;T: Area + Debug&gt;</code> のように制約のトレイトを記載します。<code>T</code> はジェネリックの型パラメータで、<code>Area</code> と <code>Debug</code> が実装された任意の型ということを示します。複数のトレイトを制約として指定したい場合には「<code>+</code>」で記載します。<code>Debug</code> は「<code>use std::fmt::Debug;</code>」で宣言する必要があるので注意してください。</p>



<p class="wp-block-paragraph">また、トレイト境界は以下のように <code><span class="jinr-d--text-color d--marker1 d--bold">where</span></code> を使用しても表現可能です。ジェネリックの型パラメータが増えた場合には <code>where</code> を使用した方が可読性が上がる可能性があります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="rust" data-enlighter-theme="" data-enlighter-highlight="3" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 面積を表示する関数 (トレイト境界を where 指定)
fn show_area&lt;T>(shape: &amp;T)
where T: Area + Debug
{
    println!("{:?}, Area: {:.2}", shape, shape.area());
}</pre>



<p class="wp-block-paragraph">ジェネリックな関数は、任意の型を受け取れる柔軟性がある一方で、関数の処理に適さない型を受け取ってしまうと予期せぬエラーが発生してしまいます。トレイト境界で、関数の処理の前提となる型の特徴を指定することができるので、安全に処理を実行できる関数を実現できます。</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 class="wp-block-paragraph">ジェネリックについては以下も参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://rust-tech.nkhn37.net/rust-generic-func-type/" target="_blank" rel="noreferrer noopener">ジェネリックな関数や型の基本を分かりやすく解説</a></p>
</div>
		</div></section>



<div id="nkhn3-1673084651" 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 class="wp-block-paragraph">Rust の<span class="jinr-d--text-color d--marker1 d--bold">トレイト（trait）</span>の基本について解説しました。トレイトとは、型に共通の振る舞いを定義する仕組みで、Rust では、データ構造と振る舞いを分離して設計する特徴があります。</p>



<p class="wp-block-paragraph">トレイトは、<code>trait</code> キーワードで定義し、各型に対して <code>impl</code> で実装をします。デフォルト実装を用意していないメソッドは必ず実装する必要があり、これにより型の利用者はトレイトのメソッドが実装されているものとして安心して利用できます。</p>



<p class="wp-block-paragraph">Rust には標準トレイトが色々と用意されていますが、<code>derive</code> による自動実装が使用できます。便利である一方で <code>Display</code> のように自動実装できないものもあります。また、自動実装が求めている結果となるかはよく確認が必要です。</p>



<p class="wp-block-paragraph">トレイトは、ジェネリックな関数に対してトレイト境界として、型が特定のトレイトを実装している必要があるという制約を表現できます。これにより安全で柔軟な関数設計ができます。</p>



<p class="wp-block-paragraph">このようにトレイトは、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 class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/trait-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-2661662311" 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-trait-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Rust入門】ジェネリックな関数や型の基本を分かりやすく解説</title>
		<link>https://rust-tech.nkhn37.net/rust-generic-func-type/</link>
					<comments>https://rust-tech.nkhn37.net/rust-generic-func-type/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Fri, 15 Aug 2025 20:00:00 +0000</pubDate>
				<category><![CDATA[Rust入門]]></category>
		<category><![CDATA[ジェネリック]]></category>
		<category><![CDATA[ジェネリック関数]]></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=399</guid>

					<description><![CDATA[Rust でジェネリックな関数や型（構造体・列挙体）を扱う方法を初心者にも分かりやすく解説します。 ジェネリック ジェネリックとは ジェネリック（generic）とは、型をパラメータとして受け取ることで、様々な異なる型に [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Rust で<span class="jinr-d--text-color d--marker1 d--bold">ジェネリック</span>な関数や型（構造体・列挙体）を扱う方法を初心者にも分かりやすく解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">ジェネリック</h2>



<h3 class="wp-block-heading jinr-heading d--bold">ジェネリックとは</h3>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">ジェネリック（generic）</span>とは、型をパラメータとして受け取ることで、様々な異なる型に対応できるようにする仕組みのことです。</p>



<p class="wp-block-paragraph">例えば、<code>i32</code> 型専用の関数を作成した場合、<code>i64</code> 型や <code>f64</code> 型に対しては、別の関数を定義しなければなりません。しかし、ジェネリックを使うことで「型に依存しない」関数にすることが可能です。Rust では、ジェネリックを関数、構造体、列挙体などで使用することができます。</p>



<p class="wp-block-paragraph">この記事では、ジェネリックな関数や型の基本について分かりやすく説明します。なお、公式ドキュメントなどではジェネリクス（generics）という複数形で表現されることも多いですが、この記事では「ジェネリックな」という表現に統一して紹介します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">ジェネリックな関数</h3>



<p class="wp-block-paragraph">Rust は型安全性が高く、コンパイル時に厳密な型チェックを行うプログラミング言語です。もし、関数を書く場合に「<code>fn func(x: i32) -&gt; i32</code>」という型注釈をつけた場合には、<code>i32</code> 型以外の型を渡すことはできません。Rust には多くの数値型があるので、関数を書くときにどの型を選ぶのか、関数名をどうするかといった煩わしさに取り組まなくてはいけなくなります。</p>



<p class="wp-block-paragraph">以降で紹介するジェネリックな関数を使うことで、この問題を解決することができます。</p>



<h4 class="wp-block-heading jinr-heading d--bold">ジェネリックな関数の定義と使い方</h4>



<p class="wp-block-paragraph">以下の例を使用して<span class="jinr-d--text-color d--marker1 d--bold">ジェネリックな関数</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 identity&lt;T>(x: T) -> T {
    x
}

// 複数の型パラメータを持つ関数
fn make_pair&lt;T, U>(x: T, y: U) -> (T, U){
    (x, y)
}


fn main() {
    let a: i32 = 10;
    let b: i64 = 50;
    let c: f64 = 100.5;

    // identity 関数の使用
    println!("{}", identity(a));
    println!("{}", identity(b));
    println!("{}", identity(c));

    // make_pair 関数の使用
    println!("{:?}", make_pair(a, b));
    println!("{:?}", make_pair(b, c));
    println!("{:?}", make_pair(c, c));
}</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
50
100.5
(10, 50)
(50, 100.5)
(100.5, 100.5)</pre>



<p class="wp-block-paragraph">上記は、受け取った引数をそのまま返却する <code>identity</code> 関数と受け取った 2 つの引数をペアのタプルにして返却する <code>make_pair</code> 関数です。</p>



<p class="wp-block-paragraph"><code>identity</code> 関数の直後に <code>&lt;&gt;</code> で囲んだ <code>T</code> という文字があります。この <code>&lt;T&gt;</code> は、関数定義の<span class="jinr-d--text-color d--marker1 d--bold">型パラメータ（type parameter）</span>と言います。これは、<code>identity</code> 関数が <code>T</code> という型パラメータで表現されるジェネリック関数であることを意味しています。</p>



<p class="wp-block-paragraph"><code>T</code> は <code>x</code> の型注釈と戻り値の型注釈に使用されています。これにより、<code>x</code> に <code>i32</code> が渡されたときは、戻り値も <code>i32</code> 型、<code>x</code> が <code>f64</code> の場合は、戻り値も <code>f64</code> というように、同じ型パラメータの部分には同一の型が入ることを示します。実際に、<code>main</code> 関数の <code>identity</code> 呼び出しでは、<code>i32</code>、<code>i64</code>、<code>f64</code> の変数を渡していますが、Rust コンパイラが型を推論することで適切に処理ができています。</p>



<p class="wp-block-paragraph">複数の型パラメータが必要となるような場合には、<code>make_pair</code> 関数での <code>&lt;T, U&gt;</code> のように複数の型パラメータを指定します。<code>T</code> や <code>U</code> の部分は任意の文字でよいですが、慣習として <code>T</code>, <code>U</code>, <code>V</code>, &#8230;といった型パラメータがよく使用されます。</p>



<p class="wp-block-paragraph">この時、<code>make_pair</code> 関数の戻り値を <code>(y, x)</code> とすると、<code>T</code>、<code>U</code> に同じ型の変数を渡す場合には問題になりませんが、型が異なる場合に不一致が発生してしまうので注意が必要です。<code>(y, x)</code> を返却するようにしたい場合には、戻り値の型パラメータを <code>(U, T)</code> とするのが適切です。</p>



<h4 class="wp-block-heading jinr-heading d--bold">明示的な型指定での呼び出し</h4>



<p class="wp-block-paragraph">Rust は型推論が強力であるため、関数に渡される変数などから型を適切に推論してくれます。型を明示的に指定して呼び出したい場合は「<code>関数名::&lt;型名&gt;()</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 a: i32 = 10;
    let b: i64 = 50;
    let c: f64 = 100.5;

    // identity 関数の使用
    println!("{}", identity::&lt;i32>(a));
    println!("{}", identity::&lt;i64>(b));
    println!("{}", identity::&lt;f64>(c));

    // make_pair 関数の使用
    println!("{:?}", make_pair::&lt;i32, i64>(a, b));
    println!("{:?}", make_pair::&lt;i64, f64>(b, c));
    println!("{:?}", make_pair::&lt;f64, f64>(c, c));
}</pre>



<p class="wp-block-paragraph">基本的には型推論に任せればよいでしょう。意図的に型を指定したい場合に、明示的に型を指定する方法があるということだけ覚えておいてもらえればと思います。</p>



<h3 class="wp-block-heading jinr-heading d--bold">ジェネリックな構造体</h3>



<h4 class="wp-block-heading jinr-heading d--bold">ジェネリックな構造体の定義と使い方</h4>



<p class="wp-block-paragraph">型パラメータは、以下のように<span class="jinr-d--text-color d--marker1 d--bold">ジェネリックな構造体</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="">// ジェネリックな構造体
struct SomeNum&lt;T, U> {
    c: char,
    num1: T,
    num2: U,
    num3: U,
}

fn main() {
    let some_number = SomeNum{
        c:'a', num1: 10, num2: 20.5, num3: 30.5
    };
    println!("{}", some_number.c);
    println!("{}", some_number.num1);
    println!("{}", some_number.num2);
    println!("{}", some_number.num3);

    let some_number1 = SomeNum{
        c: 'b', num1: 10.5, num2: 20, num3: 30
    };
    println!("{}", some_number1.c);
    println!("{}", some_number1.num1);
    println!("{}", some_number1.num2);
    println!("{}", some_number1.num3);
}</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="">【実行結果】
a
10
20.5
30.5
b
10.5
20
30</pre>



<p class="wp-block-paragraph">上記の構造体は、<code>char</code>型の<code>c</code> と、<code>T</code>、<code>U</code> という型パラメータの要素を持つ構造体となっています。<code>num1</code> は <code>T</code> 型、<code>num2</code> と <code>num3</code> は <code>U</code> 型の要素になっています。この構造体を使用する場合には、<code>num2</code> と <code>num3</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 class="wp-block-paragraph">構造体の基本については以下を参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://rust-tech.nkhn37.net/rust-structs-basic/" target="_blank" rel="noreferrer noopener">【Rust入門】構造体の使い方を分かりやすく解説</a></p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">ジェネリックな列挙体</h3>



<h4 class="wp-block-heading jinr-heading d--bold">ジェネリックな列挙体の定義と使い方</h4>



<p class="wp-block-paragraph">型パラメータは、以下のように<span class="jinr-d--text-color d--marker1 d--bold">ジェネリックな列挙体</span>の宣言にも使用することができます。列挙体の代表例である <code>Option&lt;T&gt;</code> 型や <code>Result&lt;T, E&gt;</code> 型についても、型パラメータの <code>T</code>、 <code>E</code> を持つジェネリックな列挙体となっています。</p>



<p class="wp-block-paragraph">以下では、<code>Result&lt;T, E&gt;</code> に似た独自の <code>MyResult&lt;S, F&gt;</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="">// ジェネリックな列挙体
enum MyResult&lt;S, F> {
    Success(S),    // 成功時の値
    Failure(F, String),  // 失敗時の値とエラー文字列
    Uncertainty,
}

fn main() {
    let mut result = MyResult::Success::&lt;i32, u16>(10);
    if let MyResult::Success(code) = result {
        println!("Success {}", code);
    };

    result = MyResult::Failure(1, "Error1".to_string());
    if let MyResult::Failure(code, error) = result {
        println!("Failure {} {}", code, error);
    }

    result = MyResult::Uncertainty;
    if let MyResult::Uncertainty = result {
        println!("Uncertain");
    }

    // result の S は i32型で使用しているので以下はエラーとなる
    // result = MyResult::Success(10.0);

    // 異なる型での利用
    let result = MyResult::Success::&lt;f64, u8>(10.5);
    if let MyResult::Success(code) = result {
        println!("Success {}", code);
    };
}</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="">【実行結果】
Success 10
Failure 1 Error1
Uncertain
Success 10.5</pre>



<p class="wp-block-paragraph">列挙体を使用する際には「<code>MyResult::Success::&lt;i32, u16&gt;(10)</code>」のように <code>S</code> や <code>F</code> が何の型であるかを指定して使用します。この時、型パラメータ <code>F</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 mut result: MyResult&lt;i32, u16> = MyResult::Success(10);</pre>



<p class="wp-block-paragraph">なお、コメントアウトしている「<code>result = MyResult::Success(10.0);</code>」は、既に <code>result</code> の <code>S</code> が <code>i32</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 class="wp-block-paragraph">列挙体の基本については以下を参考にしてください。</p>



<p class="wp-block-paragraph"><a href="https://rust-tech.nkhn37.net/rust-enum-basic/" target="_blank" rel="noreferrer noopener">【Rust入門】列挙型の基本を分かりやすく解説</a></p>
</div>
		</div></section>



<div id="nkhn3-1407241834" 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 class="wp-block-paragraph">ジェネリックな関数は便利ですが、任意の型でも受け入れることができてしまいます。そのため、関数内で想定していない型が渡されると、コンパイルエラーとなります。</p>



<p class="wp-block-paragraph">Rust では「<span class="jinr-d--text-color d--marker1 d--bold">トレイト</span>」という仕組みを使って型の振る舞いを定義できます。ジェネリックな関数では、型パラメータがどのトレイトを実装しているかを指定することで制約を加えることができ、これを「<span class="jinr-d--text-color d--marker1 d--bold">トレイト境界</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 std::fmt::Display;

enum MyResult&lt;S, F> {
    Success(S),    // Result
    Failure(F, String),  // FailureCode と エラー文字列
    Uncertainty,
}

// トレイト境界を指定したチェック関数
fn check_result&lt;S, F> (result: &amp;MyResult&lt;S, F>) 
where S: Display, F: Display
{
    match result {
        MyResult::Success(code) => println!("Success: {}", code),
        MyResult::Failure(code, error) => println!("Failure: {} detail: {}", code, error),
        MyResult::Uncertainty => println!("Uncertain Result")
    }
}

fn main() {
    let mut result = MyResult::Success::&lt;i32, u16>(10);
    check_result(&amp;result);

    result = MyResult::Failure(1, "Error1".to_string());
    check_result(&amp;result);
    
    result = MyResult::Uncertainty;
    check_result(&amp;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="">【実行結果】
Success: 10
Failure: 1 detail: Error1
Uncertain Result</pre>



<p class="wp-block-paragraph">上記の <code>check_result</code> 関数では、結果の形式を <code>match</code> で判定して <code>println</code> で出力していますが、その中で <code>{}</code> を指定しています。<code>{}</code> に値を埋め込むには、その型が <code>Display</code> トレイトを実装している必要があります。</p>



<p class="wp-block-paragraph"> <code>S</code>、 <code>F</code> という型パラメータが <code>Display</code> トレイトを実装していることを <code>where</code> で指定しています。「<code>fn check_result&lt;S: Display, F: Display&gt;()</code> 」と指定することも可能です。 なお、複数のトレイトを実装している必要がある場合は「<code>Display + Debug</code>」のように「<code>+</code>」でつなげていきます。</p>



<p class="wp-block-paragraph">このようにすることでジェネリックの汎用性を使いつつ、型の制約を入れることで安全な処理を設計することが可能となります。</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 class="wp-block-paragraph">トレイトの基本については以下を参考にしてください。</p>



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



<h2 class="wp-block-heading jinr-heading d--bold">ジェネリックとゼロコスト抽象化</h2>



<p class="wp-block-paragraph">Rust のジェネリックは <span class="jinr-d--text-color d--marker1 d--bold">ゼロコスト抽象化（zero-cost abstraction）</span> を実現しています。これは「抽象化を使っても、コンパイル後の実行時コストは手書きのコードと変わらない」という考え方です。プログラミング言語によっては、実行時にどの型かを判別して振る舞いを切り替えるためにパフォーマンスに影響が出る場合があります。</p>



<p class="wp-block-paragraph">Rust のジェネリックは「<strong>モノモーフィゼーション（Monomorphization）</strong>」という仕組みで処理されます。これはコンパイル時に、ジェネリック関数や型が実際に使われる具体的な型に展開して最適化されたコードを生成する仕組みです。</p>



<p class="wp-block-paragraph">例えば、上記でも紹介した <code>identity</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 identity&lt;T>(x: T) -> T {
    x
}

fn main() {
    // identity 関数の使用
    let a = identity(10);
    let b = identity(20.5);
}</pre>



<p class="wp-block-paragraph">コンパイル後には、<code>identity&lt;i32&gt;</code> と <code>identity&lt;f64&gt;</code> という型ごとの別々の関数が具体的に生成されます。そのため、実行時に型を判別して振る舞いを切り替える余分な処理が発生せず、最初から <code>i32</code> 専用関数と <code>f64</code> 専用関数を書いたかのようなパフォーマンスが得られます。</p>



<p class="wp-block-paragraph">この仕組みにより Rust は抽象化と高パフォーマンスを両立させています。「分かりやすく安全なコードを書きつつ、速度も妥協しない」という Rust の大きな強みが、ジェネリックのゼロコスト抽象化により支えられています。</p>



<div id="nkhn3-4011259523" 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 class="wp-block-paragraph">この記事では、Rust におけるジェネリックの基本について解説しました。</p>



<ul class="wp-block-list jinr-list">
<li>ジェネリックな関数を使うと、型に依存しない柔軟な関数を定義できます。</li>



<li>ジェネリックな構造体や列挙体 により、さまざまなデータ型を扱える再利用性の高い型を設計できます。</li>



<li>Rust のジェネリックは、モノモーフィゼーションによりコンパイル時に具体的な型に展開されるゼロコスト抽象化を実現しており、抽象化しても実行時のオーバーヘッドは発生しない高速な処理を実現できます。</li>
</ul>



<p class="wp-block-paragraph">ジェネリックを使うことで、安全で読みやすく、高いパフォーマンスを両立できるのが 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 class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/rust-tech-sample-source/tree/main/rust-basic/generics" 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-508525710" 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-generic-func-type/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-06-05 04:33:50 by W3 Total Cache
-->