LoginSignup
7
1

More than 1 year has passed since last update.

Traitの関数をconst fnとして実装できるようになる(かもしれない)話

Posted at

注意
この内容は2021/06/04時点での内容です。今後変更される可能性があります。
またNightly Buildでしか使用できない機能が使用されています。


タイトルだと分かりづらいですが
std::ops::Addを例にすると

struct A(i32);

const A1: A = A(1);
const A2: A = A(2);
const A3: A = A1 + A2; // A(3)になる

上記のようにユーザー定義の型に+演算子を定義してその結果をconstとして扱えるようになるという話です。

実装してみる

とりあえず型Aを定義してstd::ops::Addを実装してみます。

struct A(i32);

impl std::ops::Add<A> for A {
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
        A(self.0 + other.0)
    }
}

fn main() {
    const A1: A = A(1);
    const A2: A = A(2);
    const A3: A = A1 + A2;
    println!("{}", A3.0);
}

当然コンパイルエラーになるのでimplしたaddconst fnとして実装する必要があります。
ではどのように実装するかというと

// implとtrait名の間にconstを入れる
impl const std::ops::Add<A> for A {
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
        A(self.0 + other.0)
    }
}

こうです。
注意しなければいけないのはconst fn add(...)のように関数にconstをつけるのではなくimpl const Traitのようにimpltrait名の間にconstを入れる必要があります。

またこの機能を使用するには#![feature(const_trait_impl)]を追加する必要があるのでコード全文は以下のようになります。

#![feature(const_trait_impl)]
struct A(i32);

impl const std::ops::Add<A> for A {
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
        A(self.0 + other.0)
    }
}

fn main() {
    const A1: A = A(1);
    const A2: A = A(2);
    const A3: A = A1 + A2;
    println!("{}", A3.0);
}

Rust Playground

まとめ

  • impl const Traitと書くことでTraitの関数をconst fnとして使用できるようになる
  • #![feature(const_trait_impl)]が必要
  • 現時点(2021/6/5)ではNightly Buildのみ

おまけ

Tracking issue for RFC 2632, impl const Trait for TyというGitHubのissueがあるので気になる方はそちらを覗いてみてください。

7
1
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
7
1