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));
}


