#rust
#функция #Ржавчина #Возврат
Вопрос:
Каков правильный синтаксис для возврата функции в Rust?
Следующий код не компилируется.
fn identity<T>(a: T) -> T {
return a;
};
fn right<T>(a: T) -> Fn {
return identity;
};
Комментарии:
1. По крайней мере, вам нужно указать типы ввода и вывода:
Fn(T) -> T
Ответ №1:
Вот (игровая площадка) минимальный пример:
fn identity<T>(a: T) -> T {
return a;
}
fn right<T>(_a: T) -> impl Fn(T) -> T {
return identity;
}
fn main() {
println!("{}", right(0)(42))
}
Вам нужно:
- Укажите входной аргумент и типы вывода в подписи, т. е.
Fn(T) -> T
. - Укажите, что
right
возвращаемый типimpl
освобождает признакFn(T) -> T
.
В качестве альтернативы вы могли бы также записать указатель на функцию fn(T) -> T
в качестве возвращаемого типа. Поскольку это не черта, вам не понадобится impl
ключевое слово:
fn right<T>(_a: T) -> fn(T) -> T {
return identity;
}
Только fn
элементы и не захватывающие замыкания могут быть принудительно преобразованы в указатели функций, поэтому, хотя это проще, это будет работать не во всех случаях.
Комментарии:
1. Спасибо, на самом деле, правильный код должен быть в моем собственном ответе. Возвращаемый тип
right
не обязательно должен быть идентичен типу вводаT
identity
.2. Является ли идиоматичным использование
return identity;
вместо просто,identity
?3. @STF_ZBR Я думаю, большинству людей нравится тот факт, что блоки кода являются выражениями и опускают
return
.
Ответ №2:
Это лучшее, что я придумал:
fn identity<T>(a: T) -> T {
return a;
}
fn right<T>() -> amp;'static dyn Fn(T)->T {
return amp;identity::<T>;
}
fn main() {
println!("{}", right()(3.1415));
}
<a rel="noreferrer noopener nofollow" href="https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;code=fn identity(a: T) -> T {
return a;
}
fn right() -> &’static dyn Fn(T)->T {
return &identity::;
}
fn main() {
println!(«{}», right()(3.1415));
}» rel=»nofollow noreferrer»>игровая площадка <— протестируйте это самостоятельно.
Объяснение
amp;'static dyn Fn(T)->T
означает, что он возвращает ссылку на некоторый объект, который удовлетворяет Fn(T)->T
признаку (потому что yes Fn(T)->T
действительно является признаком, а не типом).
Комментарии:
1. Спасибо, но, как ответил @Mateen Ulhaq, это может быть просто
fn(U) -> U
, и я подумал, что это проще, не так ли?2. Да, это так! Будучи новичком, я не знал, что это возможно.
Ответ №3:
Самостоятельный ответ после двух ответов от других:
Я придумал это:
fn identity<T>(a: T) -> T {
a
};
fn right<T, U>(_a: T) -> fn(U) -> U {
identity
};
Возвращаемый тип right
не обязательно должен быть идентичен типу ввода T
identity
.