Какой смысл явного времени жизни для метода, который не принимает никаких аргументов? - PullRequest
0 голосов
/ 20 сентября 2019

На странице 295 из Programming Rust вы можете найти следующее:

К счастью, стандартная библиотека включает полную реализацию:

impl<'a, T, U> AsRef<U> for &'a T
where
    T: AsRef<U>,
    T: ?Sized,
    U: ?Sized,
{
    fn as_ref(&self) -> &U {
        (*self).as_ref()
    }
}

Я запутался в использовании &'a там.Каков контекст этого?Он не используется в аргументе as_ref и не связан с выводом &U.Я не думаю, что я полностью понимаю время жизни, когда используется в этом контексте.

Я искал это, потому что я все еще не понимал это, и ответы все еще не щелкали (имеет смысл).Я нашел convert.rs.Похоже, что это не имеет времени жизни any , но оно реализует черту AsRef.Так почему в книге есть это, а не реальный код в Rust?Где я могу найти «общую реализацию», упомянутую в книге?

Ответы [ 2 ]

2 голосов
/ 20 сентября 2019

Ссылки всегда являются общими для всей жизни.На практике &T всегда является &'a T для некоторого времени жизни, установленного компилятором в соответствии с данными обстоятельствами.Это время жизни должно быть указано в некоторым образом при реализации чего-либо для ссылочного типа.

Раньше было время, когда в утверждениях реализации не было возможности исключения времени жизни.Это изменилось в версии 1.31 компилятора, но не было необходимости изменять весь существующий, работающий код из-за этого.Код ниже работает сегодня, но не в версии 1.30.0:

trait Foo {
    fn foo(&self) {}
}

impl<T: ?Sized> Foo for &T {} // error[E0106]: missing lifetime specifier

Таким образом, параметр времени жизни 'a был сделан явным в этом случае.Единственный способ, которым это связано с временами жизни в &self и &U, заключается в том, что будет иметь место ковариация с 'a: поскольку self = &'a T связан с временем жизни 'a, также подразумевается, что &self не долженпережить всю жизнь 'a.

1 голос
/ 25 сентября 2019

Это не используется в аргументе as_ref

Это, безусловно, так.Функция использует сокращенную запись, которая может быть расширена:

fn as_ref(&self) // becomes
fn as_ref(self: &Self) // becomes
fn as_ref(self: &&'a T)

и не привязана к выводу &U

Правильно.

Так почему в книге есть это, а не реальный код в Rust?

Rust выпускает новые стабильные версии каждые 6 недель.Предположительно книги нет, поэтому вполне вероятно, что они используют более старую версию Rust.Надеемся, что в книге рассказывается о версии, с которой они разработали.

Поскольку E_net4 уже указывал , требование указать 'a в этом случае было удалено в Rust 1.31, так как задокументированов руководстве по выпуску .

Код, указанный вами в книге, соответствует , найденному в Rust 1.30 :

impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U>
{
    fn as_ref(&self) -> &U {
        <T as AsRef<U>>::as_ref(*self)
    }
}

исходный код, который вы просмотрели , соответствует Rust 1.37 :

impl<T: ?Sized, U: ?Sized> AsRef<U> for &T where T: AsRef<U>
{
    fn as_ref(&self) -> &U {
        <T as AsRef<U>>::as_ref(*self)
    }
}

Это примерно 42 недели времени разработки, достаточно для изменения исходного кода.

...