Котлин не проверяет оператор возврата в функции с некоторым типом возврата в сигнатуре

По меньшей мере четыре веские причины:

Разделение проблем

В вашем конкретном примере основанный на функторе подход имеет то преимущество, что отделяет логику итерации от логики вычисления среднего значения , Таким образом, вы можете использовать свой функтор в других ситуациях (подумайте обо всех других алгоритмах в STL), и вы можете использовать другие функторы с for_each.

Параметризация

Вы можете параметризовать функтор легче. Например, у вас может быть функтор CalculateAverageOfPowers, который принимает среднее значение квадратов, кубов и т. Д. Ваших данных, которое было бы записано так:

class CalculateAverageOfPowers
{
public:
    CalculateAverageOfPowers(float p) : acc(0), n(0), p(p) {}
    void operator() (float x) { acc += pow(x, p); n++; }
    float getAverage() const { return acc / n; }
private:
    float acc;
    int   n;
    float p;
};

Конечно, вы могли бы сделать то же самое с традиционной функцией, но затем затрудняет использование с указателями функций, потому что у него есть другой прототип CalculateAverage.

Состоятельность

И поскольку функторы могут быть stateful, вы можете сделать что-то вроде этого:

CalculateAverage avg;
avg = std::for_each(dataA.begin(), dataA.end(), avg);
avg = std::for_each(dataB.begin(), dataB.end(), avg);
avg = std::for_each(dataC.begin(), dataC.end(), avg);

, чтобы усреднить по множеству различных наборов данных.

Обратите внимание, что почти все алгоритмы STL / контейнеры, которые принимают функторы, требуют от них быть «чистыми» предикатами, т. е. не имеют наблюдаемого изменения состояния во времени. for_each является особым случаем в этом отношении (см., например, Эффективная стандартная библиотека C ++ - for_each vs. transform ).

Производительность

Функторы часто могут быть встроенный компилятором (STL - это куча шаблонов, в конце концов). В то время как теоретически это верно для функций, компиляторы обычно не будут встроены в указатель функций. Канонический пример - сравнение std::sort vs qsort;

Сводка

Конечно, можно эмулировать первые три с традиционными функциями и указателями, но при этом, как правило, 5-10 раз быстрее, если предположить, что сам предикат сравнения прост. он становится намного проще с функторами.

1
задан Abhishek Luthra 18 March 2019 в 14:59
поделиться

1 ответ

Это известная ошибка, которая присутствовала в Kotlin версии 1.3.0.

см. https://youtrack.jetbrains.com/issue/KT-28061

Если возможно, обновить до версии Kotlin> = 1.3.20

0
ответ дан Alexander Egger 18 March 2019 в 14:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: