📌

Rust文法 - アトリビュート(#[...], #![...])

2023/05/07に公開

アトリビュート(Attributes)とは

アトリビュート(Attributes)とは、「モジュール、クレート、要素(関数やImplなど)に対して付与するメタデータ」です。

アトリビュートには適用する対象によって、アウターアトリビュート(Outer Attributes)インナーアトリビュート(Inner Attributes) の2つに分けられています。

アトリビュートは以下の様な書き方で引数を取ることができます。

#[attribute = "value"]
#[attribute(key = "value")]
#[attribute(value)]

アウターアトリビュート(Outer Attributes)

#[ ... ]で宣言します。

アウターアトリビュートは、構造体、関数、列挙型、実装、トレイト、定数、モジュールなどの要素に適用されます。

例えば、#[derive(Debug)] は、Debugトレイトを自動的に実装するために構造体や列挙型に適用されます。

インナーアトリビュート(Inner Attributes)

#![ ... ]で宣言します。

インナーアトリビュートは、モジュールやクレート全体に適用されます。これらのアトリビュートは、通常クレートのルートファイル(lib.rsmain.rs)や、モジュールの先頭に記述されます。

例えば、#![allow(dead_code)]は、そのモジュールまたはクレート全体で未使用のコードに対する警告を抑制するために使われます。

アトリビュートの用途

  • コンパイル時の条件分岐(#[cfg(...)])
  • クレート名、バージョン、種類(バイナリか、ライブラリか)の設定(#![crate_name = "..."], #![crate_type = "..."], ....)
  • リントの無効化(#[allow(...)], #[warn(...)], #[deny(...)], #[forbid(...)])
  • コンパイラ付属の機能(マクロ、グロブ、インポートなど)の使用(#![feature(...)], #[derive(...)], #[macro_export], ...)
  • 外部ライブラリへのリンク(#[link(...)])
  • ユニットテスト用の関数を明示(#[test])
  • ベンチマーク用の関数を明示(#[bench])

代表的なアトリビュート

  • #[cfg]:条件付きコンパイルを実行するために使用されます。特定の条件下でのみコードをコンパイルする場合に使用します。

    #[cfg(target_os = "linux")]
    fn do_something_linux_specific() {
        // Linux固有の処理
    }
    
    • #[cfg(test)]: Rustの条件付きコンパイルアトリビュートの一つで、このアトリビュートが付与されたコードは、テストビルド時にのみコンパイルされます。
      // 通常のコード(テストと本番ビルドの両方でコンパイルされる)
      fn add(a: i32, b: i32) -> i32 {
          a + b
      }
      
      // テストビルドのみでコンパイルされるコード
      #[cfg(test)]
      mod tests {
          use super::*;
      
          #[test]
          fn test_add() {
              assert_eq!(add(1, 2), 3);
          }
      }
      
  • #[derive]:構造体や列挙型に対して自動導出(自動実装)されるトレイトを指定します

    #[derive(Debug, PartialEq, Eq, Clone)]
    struct Point {
        x: i32,
        y: i32,
    }
    
  • #[test]:テスト関数を定義します。このアトリビュートが付与された関数は、cargo testコマンドで実行されます。

    #[cfg(test)]
    mod tests {
        #[test]
        fn test_addition() {
            assert_eq!(2 + 2, 4);
        }
    }
    
  • #[allow]#[warn]#[deny]#[forbid]:これらのアトリビュートは、コンパイラの警告やエラーに対する挙動を制御します。

    #[allow(dead_code)]
    fn unused_function() {
        // この関数は未使用ですが、dead_code警告が表示されません。
    }
    
  • #[macro_export]: マクロを定義し、他のクレートからも利用できるようにします。

    #[macro_export]
    macro_rules! my_macro {
        () => {
            println!("This is my macro!");
        };
    }
    
  • #[inline]#[inline(always)]#[inline(never)]:インライン展開のヒントをコンパイラに提供します。インライン展開は、関数呼び出しのオーバーヘッドを削減する最適化手法です。

    #[inline]
    fn small_function() {
        // コンパイラにインライン展開を検討させるヒントを与えます。
    }
    
  • #![feature(<feature_name>)]: 主にnightlyの機能を利用する際に宣言します。以下は独自のテストフレームワークを実装するために、custom_test_frameworkを利用する際のコードです。

    #![feature(custom_test_frameworks)]
    #![test_runner(crate::test_runner)]
    

関連リンク

GitHubで編集を提案

Discussion