0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

(DAY17) 俺と学ぶRust言語~ジェネリクス~

Last updated at Posted at 2025-01-10

今日の内容

  • ジェネリクス

はじめに

前回は、BlackJackを完成させました。しかしながら、このシリーズの軌道が少しずれてきていた気がしたので、いったん戻ります!
今回は ジェネリクス について学びます。

ジェネリクスとは

ジェネリクス は、「特定の型に依存しないコードを書く」ための仕組みです。
Rustでは、ジェネリクスはプレースホルダのように使われ、コードを書くときには型を指定せず、コンパイル時に具体的な型が決まります。

この機能はどのような場面で使えるでしょうか?
関数で異なる型の引数を処理したり、構造体や列挙型で任意の型を格納する時などに使えます。

関数でのジェネリクス

ジェネリクスを使うと、異なる型の引数でも処理できる汎用的な関数を作成できます。

fn get_larger<T: PartialOrd>(a: T, b: T) -> T {
    if a > b {
        a
    } else {
        b
    }
}

fn main() {
    println!("{}", get_larger(10, 20));
    println!("{}", get_larger(1.2, 3.4));
}
  • : ジェネリック型を定義
  • T: PartialOrd: トレイトを実装してTが比較可能であることを指定

ここでのポイントは、ジェネリクスは 型安全 で、どの型にも対応するわけではありません。
必要に応じて トレイト境界 を追加して型の制約を設定できます。

構造体でのジェネリクス

ジェネリクスを使って、構造体のフィールドに複数の型を持たせることができます。

struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let integer_point = Point { x: 1, y: 2};
    let float_point = Point { x: 3.0, y: 4.0};

    println!("Integer Point: ({}, {})", integer_point.x, integer_point.y);
    println!("float Point: ({}, {})", float_point.x, float_point.y);
}
/******** 実行結果 ********
Integer Point: (1, 2)
float Point: (3, 4)
*************************/
  • <T>は任意の型を表す
  • Point<T>はどの型でも扱える汎用的な構造体

列挙型でのジェネリクス

列挙型もジェネリクスを使って柔軟に設計できます。

fn main() {
    let some_number = Some(5);
    let some_string = Some("Hello");

    println!("{:?}", some_number);
    println!("{:?}", some_string);
}
/******** 実行結果 ********
Some(5)
Some("Hello")
*************************/

Rust標準ライブラリの Option型 はジェネリクスを活用した代表的な例です。
Option型は次回学びます。

トレイト境界

ジェネリクスを使う場合、ある特定のトレイトを実装した型だけを許可することができます。これを トレイト境界 と呼びます。

fn print_display<T: std::fmt::Display>(value: T) {
    println!("{}", value);
}

fn main() {
    print_display(123);
    print_display("Hello");
    // print_display(vec![1, 2, 3]);
}
/******** 実行結果 ********
123
Hello
*************************/

「123」という整数や「Hello」というような文字列はDisplayを実装していますが、Vecは実装してないので、print_display(vec![1, 2, 3]);はエラーになります。

おわりに

今回はRustでのジェネリクスについて学びました。
次回は、Option型について学ぼうと思います。
ご精読ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?