Каков правильный синтаксис для возврата функции в Rust?

#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 .