Говоря об иерархии, подобной LLVM, я имею в виду способ получения полиморфизма во время выполнения, описанный в этой документации: https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html.
Легко реализовать то же самое функция в Rust с использованием перечислений, например:
enum Shape {
Square(Square),
Circle(Circle)
}
enum Square {
SquareA(SquareAData),
SquareB(SquareBData),
}
enum Circle {
CircleA(CircleAData),
CircleB(CircleBData),
}
// assume ***Data can be arbitrarily complex
Однако макет памяти неизбежно отличается от иерархии наследования, подобной LLVM, которая использует одно целочисленное поле для записи дискриминант типа. Хотя текущая ржавчина c уже имеет много оптимизаций по размеру перечислений, все равно будет два целочисленных поля для записи дискриминанта в Shape
объекте в приведенном выше примере.
Я пробовал несколько пути без успеха, в которых у меня на уме скрытность от LLVM-подобной иерархии наследования - включить ночные функции arbitrary_enum_discriminant
и назначить каждому варианту перечисления дискриминант:
#![feature(arbitrary_enum_discriminant)]
enum Shape {
Square(Square),
Circle(Circle)
}
#[repr(usize)]
enum Square {
SquareA(SquareAData) = 0,
SquareB(SquareBData) = 1,
}
#[repr(usize)]
enum Circle {
CircleA(CircleAData) = 2,
CircleB(CircleBData) = 3,
}
Это вполне возможно для * От 1020 * до go без собственного дискриминанта, так как два его варианта имеют непересекающиеся множества дискриминантов. Однако ржавчина c все еще присваивает ему целочисленный дискриминант, делая его больше, чем Square
или Circle
. (rust c версия: rustc 1.44.0-nightly (f509b26a7 2020-03-18)
)
Поэтому мой вопрос: возможно ли в Rust использование enum для моделирования иерархии, подобной LLVM, с единственным целочисленным дискриминантом на верхнем уровне? "класс"?