Functions
## Learning Objectives
- Define and call functions
- Understand parameters and return values
- Master optional and named parameters
- Learn arrow functions and typedefs
## Defining Functions
### Basic Structure
```dart
void greet() {
print('Hello!');
}
void main() {
greet(); // Hello!
}
```
### Function with Return Type
```dart
int add(int a, int b) {
return a + b;
}
void main() {
int result = add(5, 3);
print(result); // 8
}
```
### Return Type Inference
```dart
void main() {
// Dart can infer return type for simple functions
var add = (int a, int b) => a + b;
print(add(5, 3)); // 8
}
```
## Parameters
### Positional Parameters
```dart
void printName(String firstName, String lastName) {
print('$firstName $lastName');
}
void main() {
printName('John', 'Doe'); // John Doe
}
```
### Optional Positional Parameters
```dart
String greet(String name, [String? title]) {
if (title != null) {
return '$title $name';
}
return name;
}
void main() {
print(greet('Alice')); // Alice
print(greet('Bob', 'Mr.')); // Mr. Bob
}
```
### Default Parameter Values
```dart
String greet(String name, [String title = 'Mr.']) {
return '$title $name';
}
void main() {
print(greet('Alice')); // Mr. Alice
print(greet('Bob', 'Dr.')); // Dr. Bob
}
```
### Named Parameters
```dart
void createUser({
required String name,
int age = 18,
String city = 'Unknown',
}) {
print('User: $name, Age: $age, City: $city');
}
void main() {
createUser(name: 'Alice', age: 25, city: 'NYC');
createUser(name: 'Bob'); // Uses defaults for age and city
}
```
### Required Named Parameters
```dart
void createUser({
required String name,
required int age, // Must be provided
String? email, // Optional
}) {
print('User: $name, Age: $age, Email: $email');
}
void main() {
createUser(name: 'Alice', age: 25); // OK
// createUser(name: 'Bob'); // Error: age is required
}
```
## Return Values
### void (No Return)
```dart
void printSum(int a, int b) {
print('Sum: ${a + b}');
}
```
### Return Early
```dart
String getGrade(int score) {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
return 'F';
}
```
### Multiple Returns (Guard Clauses)
```dart
bool validate(int age, String? name) {
if (age < 0) return false;
if (name == null || name.isEmpty) return false;
return true;
}
```
## Arrow Functions
### Single Expression
```dart
int square(int x) => x * x;
void main() {
print(square(5)); // 25
}
```
### With Block Body
```dart
int square(int x) {
return x * x;
}
```
### In Collections
```dart
void main() {
var numbers = [1, 2, 3, 4, 5];
var doubled = numbers.map((n) => n * 2);
print(doubled.toList()); // [2, 4, 6, 8, 10]
var evens = numbers.where((n) => n % 2 == 0);
print(evens.toList()); // [2, 4]
}
```
## Anonymous Functions
### Lambda Expressions
```dart
void main() {
var multiply = (int a, int b) => a * b;
print(multiply(3, 4)); // 12
var numbers = [1, 2, 3];
numbers.forEach((n) => print(n));
}
```
### Closure
```dart
Function makeAdder(int addBy) {
return (int n) => n + addBy;
}
void main() {
var add2 = makeAdder(2);
var add10 = makeAdder(10);
print(add2(5)); // 7
print(add10(5)); // 15
}
```
## Higher-Order Functions
### Functions as Parameters
```dart
void executeTwice(Function f) {
f();
f();
}
void main() {
executeTwice(() => print('Hello'));
}
```
### Functions Returning Functions
```dart
Function operation(String type) {
switch (type) {
case 'add':
return (a, b) => a + b;
case 'subtract':
return (a, b) => a - b;
default:
return (a, b) => 0;
}
}
void main() {
var add = operation('add');
print(add(10, 5)); // 15
}
```
## Typedef
### Function Type Alias
```dart
typedef Calculate = int Function(int, int);
int add(int a, int b) => a + b;
int subtract(int a, int b) => a - b;
void main() {
Calculate calc = add;
print(calc(10, 5)); // 15
calc = subtract;
print(calc(10, 5)); // 5
}
```
### With Named Parameters
```dart
typedef UserCreator = User Function({
required String name,
required int age,
});
User createUser({required String name, required int age}) {
return User(name, age);
}
void main() {
UserCreator creator = createUser;
var user = creator(name: 'Alice', age: 30);
}
```
## Recursion
### Factorial
```dart
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
void main() {
print(factorial(5)); // 120
}
```
### Iterative Alternative
```dart
int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
```
## Scope
### Local Variables
```dart
void main() {
var x = 'outer';
void inner() {
var x = 'inner';
print(x); // inner (shadows outer)
}
inner();
print(x); // outer
}
```
## Summary
- Functions: `return_type name(params) { }`
- Arrow: `int square(int x) => x * x;`
- Named params: `func({required int a, int b = 5})`
- Optional positional: `func(a, [b])`
- `typedef` creates function type aliases
- Anonymous functions: `(params) => expression`
- Functions are first-class: can be passed/returned
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →