TLDR: Практической разницы нет.
Следует понимать, что показатели времени жизни Rust не являются строгим утверждением равенства, вместо этого они обозначают отношения «длиннее, чем». Поэтому, когда вы пишете:
fn foo<'a> (x: &'a i32)
Вы говорите компилятору, что: «Чтобы вызвать foo
, должно существовать некоторое время жизни 'a
, а x
должен жить как минимум столько, сколько 'a
(но x
может жить дольше, чем это) ".
Возвращаясь к определениям вашей функции:
fn test1<'a, 'b: 'a>(x: &'a u32, y: &'b u32) -> &'a u32
Это означает:
- Там должно существовать некоторое время жизни
'a
, такое, что x
живет по крайней мере столько же, сколько 'a
(но может жить дольше). - Должно существовать некоторое время жизни
'b
, которое по крайней мере столько, сколько 'a
(но может быть таким же), так что y
живет как минимум столько же, сколько 'b
(но может жить дольше). - И возвращаемое значение не может жить дольше, чем
'a
.
Поскольку на 'b
нет других ограничений, компилятор всегда может выбрать 'b = 'a
, и код будет компилировать, пока выполняются ограничения на 'a
.
Когда вы вызываете функцию, компилятор ищет некоторые времена жизни 'a
и 'b
, которые соответствуют вышеуказанным ограничениям:
let a = 5;
{
let b = 6;
let c = test1(&a, &b);
println!("{}", c);
}
- Возвращаемое значение не может жить дольше, чем
'a
, поэтому 'a
должно начинаться с вызова функции (потому что возвращаемое значение не существует раньше ) и заканчиваются на закрывающей скобке в ближайшее время. - Здесь
x
равно a
, а x
должно жить как минимум столько же, сколько 'a
. Поскольку a
определено до вызова функции и все еще живо в закрывающей скобке, все в порядке. - Здесь
y
равно b
, а y
должно жить как минимум столько же, сколько и 'b
. Если мы выберем 'b = 'a
, то все в порядке, поскольку b
определено до вызова функции и действует до закрывающей фигурной скобки.
Поэтому компилятор выбирает 'a == 'b
, начиная с вызова функции и заканчивается на закрывающей скобке. Обе переменные a
и b
живут дольше, чем это, но это нормально, так как аннотации времени жизни для параметров являются нижними границами истинного времени жизни соответствующих переменных.
Примечание: то же самое рассуждение применимо к вашей второй функции и снова компилятор всегда может выбрать 'b = 'a
всякий раз, когда соблюдаются все другие ограничения.