Size: a a a

Rust — русскоговорящее сообществo

2020 September 10

X

XÆA-XII in Rust — русскоговорящее сообществo
Куда смотреть? В AsyncReader?
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
XÆA-XII
Куда смотреть? В AsyncReader?
Я бы сказал, что в event
источник

X

XÆA-XII in Rust — русскоговорящее сообществo
Спасибо
источник

EG

Emmanuel Goldstein in Rust — русскоговорящее сообществo
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
А как правильно пользоваться Box<dyn Any> и даункастами, если мне нужно хранить более конкретный Box<dyn MyTrait> внутри моей либы, а снаружи иметь возможность кастить в конкретный тип как это делается с Any?
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=691fae5a609d02c06c244d95055eeb37

Вот тут я храняю строку в Box<dyn Debug>, но при попытке откастить в строку получаю None
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
fn main() {
   let x: Box<dyn Debug> = Box::new("Hi".to_string());
   println!("&x: {:?}", &x);
   println!("&x as Any->String: {:?}", (&x as &dyn Any).downcast_ref::<String>());
}

&x: "Hi"
&x as Any->String: None
источник

AK

Adam K in Rust — русскоговорящее сообществo
Oleg Andreev
А как правильно пользоваться Box<dyn Any> и даункастами, если мне нужно хранить более конкретный Box<dyn MyTrait> внутри моей либы, а снаружи иметь возможность кастить в конкретный тип как это делается с Any?
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
т.е. я так понимаю, задача нетривиальная?
источник

AK

Adam K in Rust — русскоговорящее сообществo
Oleg Andreev
т.е. я так понимаю, задача нетривиальная?
Да, не. Скорее проблема в том, что бойлерплейта для этого порядочно нужно. Макрос в этом крейте его генерит, собственно.
источник

AK

Adam K in Rust — русскоговорящее сообществo
Но можно и ручками написать
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
а есть где-нить дока про трюк?
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
я так понимаю, что Box<dyn MyTrait> стирает информацию про оригинальный тип, оставляя ее где-то в диспатч-таблице, а в боксе остается только информация про MyTrait?
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
поэтому кастинг через Any не дает возможность получить ссылку на оригинальный тип?
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
т.е. нужно начинать с Box<ConcreteType> и его уже кастить в какой-нить Box<dyn MyTrait> перед тем как положить внутрь либы?
источник

AK

Adam K in Rust — русскоговорящее сообществo
Oleg Andreev
поэтому кастинг через Any не дает возможность получить ссылку на оригинальный тип?
У тебя для того чтобы из трейт обжекта вытащить его тип, в vtable должен быть метод type_id. В vtable твоего трейта его нету.
Решение - объявлять свой трейт как расширение Any - trait MyTrait: Any { ... }
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
О. Лофко, щас попробуем
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
не, не работает
источник

AK

Adam K in Rust — русскоговорящее сообществo
Ну это не все, там ещё чет подшаманить надо. Можно cargo expand на этот макрос сделать и посмотреть, что там в выхлопе.
источник

OA

Oleg Andreev in Rust — русскоговорящее сообществo
trait MyTrait: Any + Debug {
   fn foo(&self) -> String {
       "MyTrait::foo()".to_string()
   }
}

impl MyTrait for String {}

fn main() {
   let x: Box<dyn MyTrait> = Box::new("Hi".to_string());
   println!("&x: {:?}", &x);
   println!("&x.foo(): {:?}", &x.foo());
   println!("&x as Any->String: {:?}", (&x as &dyn Any).downcast_ref::<String>());
}


вот тут все равно None в конце
источник