るいもの戯れ言
#199
2017/01/21 10:57

Rustで以下のようなJavaのenumを実現したい。


public enum SharpFlat {
    SHARP(1), DOUBLE_SHARP(2), NATURAL(0), NULL(0), FLAT(-1), DOUBLE_FLAT(-2);

    private final byte offset;

    private SharpFlat(int offset) {
        this.offset = (byte)offset;
    }

    public int getOffset() {
        return offset;
    }
}

RustのenumはJavaとかのenumとは考え方が違って直和型の定義のようだ

structで定義してもいいけど、enumになっていればexhaustive checkされるので、やはりenumの方がありがたい。試してみると、enumもtraitを実装できるので、以下のようにすることで解決できた。


enum SharpFlat {
    SHARP,
    FLAT,
}

trait HasOffset {
    fn offset(&self) -> i8;
}

impl HasOffset for SharpFlat {
    fn offset(&self) -> i8 {
        match *self {
            SharpFlat::SHARP => 1,
            SharpFlat::FLAT => -1,
        }
    }
}

fn foo(sharp_flat: Option<SharpFlat>) {
    match sharp_flat {
        None => {
            println!("none");
        },
        Some(SharpFlat::SHARP) => {
            println!("sharp {}", SharpFlat::SHARP.offset());
        },
        Some(SharpFlat::FLAT) => {
            println!("flat");
        },
    }
}

fn main() {
    foo(Some(SharpFlat::SHARP));
}