注意
この内容は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したadd
をconst 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
のようにimpl
とtrait
名の間に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);
}
まとめ
-
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があるので気になる方はそちらを覗いてみてください。