Как мне объявить обычную (незамкнутую) функцию, которая соответствует типу функции? - PullRequest
0 голосов
/ 19 июня 2019

У меня есть коллекция различных функций сортировки с общей подписью, поэтому они могут быть взаимозаменяемо переданы другим функциям. Я хочу иметь возможность объявить inline, что каждый из них должен соответствовать одной и той же подписи, поэтому я буду предупрежден контекстуально, если один из них порвет с этим.

Rust имеет синтаксис для объявления типов функций:

type Foo = Fn(i32) -> i32;

fn bar(func: &Foo) {
    func(12);
}

Я не могу понять, как объявить обычную (незамкнутую) функцию, которая соответствует типу функции:

// this works and can be passed as a Foo, but 
// duplicates code and isn't checked against Foo
fn blah(x: i32) -> i32 {
    return x * 2;
}

// this isn't valid syntax
fn blah(x): Foo {
    return x * 2;
}

Это распространенная практика в некоторых других языках, которые имеют типы функций. Есть ли синтаксис, о котором я не знаю, это будущая функция или есть какая-то техническая причина, препятствующая его добавлению в Rust?

Примечание; что-то вроде этого также послужило бы моей цели, хотя это было бы более неуклюже:

fn blah(x: i32) -> i32 {
    return x * 2;
}: Foo

1 Ответ

3 голосов
/ 19 июня 2019

Rust имеет синтаксис для объявления типов функций:

type Foo = Fn(i32) -> i32;

Это не такой синтаксис (как вы могли бы понять из-за того, что он неделай что хочешь).Это создает псевдоним типа dyn Fn(i32) -> i32.

. Вы можете достичь того, чего хотите, используя указатель на функцию и создав неиспользуемую переменную, установленную для функции:

type MyType = fn(i32) -> i32;

fn blah(x: i32) -> i32 {
    x * 2
}

const _IGNORE: MyType = blah;

Тем не менее, я согласен с комментариями, что вы идете по этому поводу не-идиоматически в стиле Rust.Вы хотите создать интерфейс, которого придерживаются вещи, и в Rust это черта :

trait Sort {
    fn foo(_: i32) -> i32;
}

struct A;
impl Sort for A {
    fn foo(x: i32) -> i32 {
        x * 2
    }
}

Это предотвращает случайное «пересечение потоков», предоставляяfn(String) когда вы имели в виду fn(String);первый - «напечатать эту строку», а второй - «удалить файл с именем».Сигнатуры функций в лучшем случае являются слабым интерфейсом.

См. Также:

...