Они делают несколько разные вещи, которые могут или не могут действовать одинаково в зависимости от того, как вы их используете.
1.
Function calc1 = add;
Объявляет переменную типа Function
и присваивает ссылка на функцию add
к нему. Если add
является переменной верхнего уровня, stati c или локальной переменной, то все ссылки на нее будут иметь одно и то же значение. Если вы ссылаетесь на функцию экземпляра (метод), вы каждый раз создаете новое замыкание.
2.
Function calc2=(int n1,int n2) {
return n1+n2;
};
Объявляет переменную с типом Function
, затем оценивает функциональный литерал к значению функции. Каждое вычисление этого литерала создает новый объект.
3.
var calc3=(int n1,int n2)=>{
n1+n2
};
Вероятно, вы хотели написать
var calc3=(int n1,int n2)=>
n1+n2;
Это почти эквивалентно 2. Тело of => expression;
- это сокращение от { return expression; }
. Однако вы объявляете переменную как var
, а не Function
, поэтому вывод типа дает переменной тип int Function(int, int)
.
4.
var callc=(int n1,int n2) {
return n1+n2;
};
Полностью эквивалентно 3, если вы делаете это как локальную переменную, но как переменную верхнего уровня, вывод типа не смотрит в тело, чтобы найти возвращаемый тип.
То, что вы видите, не является ошибкой, а просто полезной информацией. Я тоже не совсем уверен, что это правильно. Когда я проверяю cpde в DartPad, он фактически выводит int Function(int, int)
вместо var x = (int x, int y) { return x + y; };
.
Самая большая разница между разными случаями на практике состоит в том, что номер 1 не создает новое закрытие при каждой оценке, и номера 1 и 2 имеют тип Function
вместо int Function(int, int)
. Это влияет на проверку типов, потому что Function
разрешает любой вызов, в то время как точный тип функции позволяет вызывать функцию только с двумя целыми числами (и знает, что результат является целым числом).