Добрый вечер!
В Rust нет сабтайпинга, как и нет понятия равенства ссылок - отношение равенства определено только над значениями и "проходит сквозь" ссылки. Поэтому если пытаться реализовать ваш подход непосредственно, и если вам на самом деле нужно *только* сравнивать сыылки, то вам придётся использовать сырые указатели, и в этом случае отношение подтипов совершенно не нужно:
struct S2<A, B>;
struct S1<A> {
refs: Vec<*const ()>
}
impl<A> S1<A> {
fn new() -> S1<A> {
S1 { refs: Vec::new() }
}
fn push<B>(&mut self, r: &S2<A, B>) {
self.refs.push(r as *const _ as *const ());
}
fn compare(&self, i1: uint, i2: uint) -> bool {
self.refs[i1] == self.refs[i2]
}
}
fn main() {
let mut s: S1<int> = S1::new();
let x: S2<int, f64> = S2;
let y: S2<int, String> = S2;
s.push(&x);
s.push(&x);
s.push(&y);
println!("{}", s.compare(0, 1));
println!("{}", s.compare(0, 2));
}
Это, однако, очень сомнительный подход - в Rust равенство ссылок не определено, и вообще ссылки очень хрупки. Из-за того, что в этом коде они преобразовываются в сырые указатели, информация о их времени жизни недоступна внутри S1, поэтому они могут легко стать "висячими". Пока вы не разыменовываете их (для этого потребуется unsafe-блок), вы не получите сегфолтов и прочих пакостей, но логика программы в целом может пострадать. Кроме того, в этом случае вы не сможете безопасно получить доступ к самим объектам типа S2<A, *> в принципе.
Общего способа же абстрагироваться от одного типового параметра я не знаю. Вы можете использовать Any (если все ваши типы S2<A, *> являются 'static), но в этом случае вам придётся делать downcast каждый раз, когда вам понадобится работать с объектами этого типа непосредственно. По идее, здесь могло бы помочь наследование трейтов:
trait S2P<A> : Any {}
Downcast бы всё равно потребовался, но типы можно было бы задать более строго. Однако наследование пока не работает правильно вместе с trait objects, которые здесь тоже понадобятся, поэтому вам это не подойдёт.
Возможно, если вы разъясните свой юзкейс поподробнее, я смогу подсказать более идиоматичное для Rust решение.
среда, 17 декабря 2014 г., 10:34:23 UTC+1 пользователь Mike Potanin написал: