Функция может принимать параметры. Параметры перечисляются в скобках после имени функции имеют следующее определение:
тип название_параметра
Стоит отметить, что ранее уже использовалась одна функция, которая принимает параметры - это функция print()
. Она через параметр принимает некоторое значение и выводит его на консоль.
И благодаря параметру мы можем передавать в функцию различные значения и выводить их на консоль.
void main() { print("Hello"); print(22); print("metanit.com"); }
Определим свою функцию, которая принимает параметры. Пусть она складывает два числа:
void main() { sum(2, 5); // 7 } void sum(int a, int b){ int c = a + b; print(c); }
Функция sum принимает два параметра, которые имеют имена a и b и представляют тип int
. В функции main вызываем функцию sum и передаем ей два аргумента.
Аргументы - это значения для параметров функции. Аргументы передаются параметрам по позиции. То есть первый аргумент передается первому параметру, второй
аргумент - второму параметру и так далее. В данном случае параметр a в качестве значения получит число 2, а параметр b - число 5.
Количество передаваемых аргументов должно соответствовать количеству параметров. Кроме того между типами аргументов и типами параметров должно быть соответствие. Например, определим еще одну функцию:
void main() { printPerson("Tom", 35); printPerson("Alice", 29); } void printPerson(String name, int age){ print("Name: $name"); print("Age: $age \n"); }
Функция printPerson принимает два параметра. Первый параметр представляет тип String, а второй представляет тип int. Поэтому при вызове функции необходимо сначала передать значение типа String (то есть строку), а затем значение типа int (то есть целое число)
При определении функции мы можем не указывать тип параметров. Тогда Dart сам выводит их тип исходя из передаваемых значений:
void main() { printPerson("Tom", 35); printPerson(29, "Alice"); } void printPerson(name, age){ print("Name: $name"); print("Age: $age \n"); }
Обратите внимание, что теперь при определении функции неизвестно, какой именно тип представляют параметры name и age. Формально в качестве типа будет применяться dynamic. То есть предыдущее определение функци printPerson будет аналогично следующему:
void printPerson(dynamic name, dynamic age){ print("Name: $name"); print("Age: $age \n"); }
Поэтому во втором вызове функции
printPerson(29, "Alice")
Dart будет трактовать параметр name как параметр типа int, потому что ему передается целое число. А параметр age будет трактоваться как строка.
Ряд параметров мы можем сделать необязательными, то есть мы можем не передавать для них никаких значений. Для этого параметр заключается в квадратные скобки. Но при этом ему необходимо предоставить значение по умолчанию, которое будет использоваться, если параметру не передано никакого значения:
void main() { printPerson("Tom", 35); printPerson("Alice"); } void printPerson(String name, [int age = 22]){ print("Name: $name"); print("Age: $age \n"); }
В данном случае параметр age является необязательным. Если мы не передадим ему никакого значения, то он по умолчанию будет иметь значение 22. Консольный вывод:
Name: Tom Age: 35 Name: Alice Age: 22
Следует учитывать, что необязательные параметры, должны идти после обязательных. Так, в примере выше необязательный параметр age идет после обязательного параметра name.
Также может быть несколько необязательных параметров, и все помещаются в квадратные скобки:
void main() { printPerson("Tom"); } void printPerson(String name, [int age = 22, String company = "Undefined"]){ print("Name: $name"); print("Age: $age"); print("Company: $company \n"); }
В данном случае 2 необязательных параметра - age и company.
Однако если необязательный параметр представляет nullable-тип, то есть может принимать значение null, тогда можно не указывать для него значение по умолчанию - в этом случае значение по умолчанию будет null:
void main() { printPerson("Tom", 35); printPerson("Alice"); } void printPerson(String name, [int? age]){ print("Name: $name"); if(age!=null){ print("Age: $age \n"); } }
Консольный вывод:
Name: Tom Age: 35 Name: Alice
Dart поддерживает передачу параметров по имени. Например:
void main() { printPerson(name: "Tom", age: 35); printPerson(age: 29, name: "Alice"); printPerson(name: "Kate"); } void printPerson({String name = "undefined", int age=0}){ print("Name: $name"); print("Age: $age \n"); }
При определении функции список параметров заключается в фигурные скобки, при этом для каждого параметра, если его тип не поддерживает значение null, указывается значение по умолчанию.
При вызове функции указывается имя параметра и через двоеточие его значение (name: "Tom"
), при этом мы можем указывать параметры в любой последовательности.
Например, во втором вызове вначале указывается значение для параметра age, а потом для параметра name (printPerson(age: 29, name: "Alice")
).
Более того мы можем вообще не передавать параметрам значение, тогда подобный параметр будет иметь значение по умолчанию, как в случае с параметром age в третьем вызове (printPerson(name: "Kate")
).
Консольный вывод:
Name: Tom Age: 35 Name: Alice Age:29 Name: Kate Age: 0
Если параметр представляет nullable-тип, то есть поддерживает значение null, то мы можем не указывать значение по умолчанию, тогда значением по умолчанию будет null:
void main() { printPerson(age: 35); printPerson(age: 29, name: "Alice"); printPerson(name: "Kate"); } void printPerson({String? name = "undefined", int? age}){ print("Name: $name"); if(age != null){ print("Age: $age \n"); } }
Консольный вывод программы:
Name: undefined Age: 35 Name: Alice Age: 29 Name: Kate
Именнованные параметры по умолчанию необязательные. То есть мы можем указать для них значение по умолчанию, а при вызове функции не передавать этим параметрам значения. Однако иногда бывать необходимо, чтобы параметр был, с одной стороны, именованным, а, с другой стороны, обязательным. Для этого применяется оператор required, который указывается перед параметром. Например, сделаем обязательным параметр name:
void main() { printPerson(age: 29, name: "Alice"); printPerson(name: "Kate"); // printPerson(age: 35); // ! Ошибка - для name надо указать значение } void printPerson({required String name, int age = 22}){ print("Name: $name"); print("Age: $age\n"); }
В этом случае для параметра name надо обязательно указать значение, при этом ему можно передать значение по имени.
Параметры позволяют передать значения локальным переменным, которые определены в функциях. Но также можно передавать через параметры значения локальным final-константам, поскольку они определяются во время выполнения. Но при этом мы не можем передавать значения const-константам, так как их значения должны известны уже во время компиляции. В связи с чем при разных вызовах функции мы можем передать final-константам разные значения:
void main() { printPerson("Tom", 35); printPerson("Alice", 22); } void printPerson(String userName, int userAge){ // const int initialAge = userAge; - так нельзя, константа должна определяться на этапе компиляции final String name = userName; final int age = userAge; print("Name: $name Age: $age \n"); }
Консольный вывод программы:
Name: Tom Age: 35 Name: Alice Age: 22