05_Cairo 中の Enum(列挙型)#
この記事で使用されている Cairo コンパイラのバージョン:2.0.0-rc0。Cairo は急速に更新されているため、異なるバージョンでは文法にわずかな違いがあるかもしれませんが、将来的には安定したバージョンに記事の内容を更新する予定です。
Cairo の Enum は、一連のタイプの列挙型であり、複数のサブタイプが 1 つの列挙型を共有することができます。適用されるシナリオは、共通点を持つ一連のタイプがあり、各タイプが異なり、同時に相互に排他的である場合です。
基本的な使用方法の紹介#
例えば:IP には 2 つのバージョン、IPV6 と IPV4 があります。これらのバージョンはどちらも IP のバージョン番号であり、同じ値は常に 1 つのタイプになります。この場合、Enum を使用することができます。定義方法は次の通りです。
enum IpAddrKind {
V4:(),
V6:(),
}
Enum を使用して変数をインスタンス化する
let four = IpAddrKind::V4(());
let six = IpAddrKind::V6(());
V4 と V6 は、関数の引数として、どちらも IpAddrKind の 1 つのタイプとして扱うことができます。
#[derive(Drop)]
enum IpAddrKind {
V4: (),
V6: (),
}
fn route(ip_kind: IpAddrKind) {}
fn main() {
route(IpAddrKind::V4(()));
route(IpAddrKind::V6(()));
}
Enum にタイプを追加する#
Rust と同様に、さまざまなタイプを Enum に追加することができます。Enum の各要素は、タイプのエイリアスのようなものです。
#[derive(Drop)]
enum Message {
Quit: (),
Echo: felt252,
Move: (usize, usize),
ChangeColor: (u8, u8, u8)
}
fn route(msg: Message) {}
fn main() {
route(Message::Quit(()));
route(Message::Echo(20));
route(Message::Move((32_usize, 32_usize)));
route(Message::ChangeColor((8_u8, 8_u8, 8_u8)));
}
上記の例では、felt252 と tuple を Message という enum に追加し、対応するタイプの変数を route のパラメータとして使用しています。
Enum に impl を追加する#
structに impl を追加して、関数を定義することができるのと同様に、enum でも使用することができます。以下はコードの例です。
use debug::PrintTrait;
#[derive(Drop)]
enum Message {
Quit: (),
Echo: felt252,
Move: (usize, usize),
ChangeColor: (u8, u8, u8)
}
trait Processing {
fn process(self: Message);
}
impl ProcessingImpl of Processing {
fn process(self: Message) {
match self {
Message::Quit(()) => {
'quitting'.print();
},
Message::Echo(value) => {
value.print();
},
Message::Move((x, y)) => {
'moving'.print();
},
Message::ChangeColor((x, y, z)) => {
'ChangeColor'.print();
},
}
}
}
これにより、データ型に非常に豊かさがもたらされます。