#rust
После перехода с январьской версии компилятора Rust на beta. Обнаружил что код подобный этому не компилируется http://is.gd/oX7GWN: use std::fmt::{Display, Formatter, Error}; struct MyLocalType; type MyResult = Result; impl Display for MyResult { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { f.write_str("some test string") } } fn main() { let r: MyResult = Ok(MyLocalType); println!("{}" , r); } Это ошибка компилятора, или теперь внешние параметризованные типы нужно всегда "заворачивать" в свои ?
Ответы
Ответ 1
Ответ, скопированый с англоязычного stackoverflow: https://stackoverflow.com/questions/29789877/can-not-implement-trait-from-another-crate-for-generic-type-from-another-crate-p There's no direct way to solve this for a pure alias like type. The code is the same as impl Display for Resultand the compiler can't ensure that there will be no conflicting implementations in other crates (aka, can't ensure that the implementation is 'coherent'). Being able to do it is definitely useful sometimes, but it was unfortunately a bug that the compiler accepted it before. Solutions include: defining a proper wrapper type for Result, e.g. struct MyResult(Result );, defining your own enum: enum MyResult { Ok(MyType), Err(String) }, define a wrapper type, but only use it when printing, i.e. write println!("{}", Wrapper(r)); instead of println!("{}", r);. Both of these make MyResult a local type, and so the impl then should be legal. Описание на русском, как его понял я: Теперь нет способа реализовывать типаж для стороннего обобщённого типа, пусть даже и параметризованного локальным типом. Так как компилятор не может быть уверен, что реализация будет согласована со всеми другими реализациями. Чтобы решить эту проблему нужно сделать тип полностью локальным. Eсть несколько способов: «Обернуть» его в локальный тип-обёртку, например: struct MyResult(Result ); Объявить свой собственный Result-подобный тип: enum MyResult { Ok(MyType), Err(String) } Или же обернуть его, но использовать обёртку только там, где необходим требуемый типаж, например: println!("{}", Wrapper(r)); вместо println!("{}", r);
Комментариев нет:
Отправить комментарий