openplanning

Hướng dẫn và ví dụ hàm trong Dart

  1. Hàm là gì?
  2. Hàm thông thường
  3. Closure (Bao đóng)
  4. Tham số tuỳ chọn
  5. Tham số tuỳ chọn được đặt tên

1. Hàm là gì?

Trong ngôn ngữ lập trình Dart, hàm (function) là một khối mã (block of code) được đặt tên. Nó có thể bao gồm các tham số và trả về một giá trị hoặc không trả về gì cả, và chỉ chạy khi được gọi. Các hàm chia nhiệm vụ lớn thành các phần nhỏ và thực hiện hoạt động cụ thể của chương trình đó. Quá trình này làm tăng khả năng tái sử dụng mã và nâng cao cách tiếp cận mô-đun của chương trình.
return_type function_name(arguments)  {
   // Statements
}
Chú ý: Cũng giống như JavaScript, Dart không cho phép 2 hàm cùng tên, kể cả khi chúng có các tham số khác nhau.

2. Hàm thông thường

Cú pháp khai báo một hàm thông thường:
return_type function_name(data_type1 arg1, data_type2 arg2, data_typeN argN)  {
   // Statements
}
Sử dụng từ khoá void (Hoặc rỗng) như một kiểu trả về nếu hàm không trả về gì cả.
void function_name(data_type1 arg1, data_type2 arg2, data_typeN argN)  {
   // Statements
}
// Same as:
function_name(data_type1 arg1, data_type2 arg2, data_typeN argN)  {
   // Statements
}
Ví dụ: Hàm sum với hai tham số kiểu int, và trả về một giá trị kiểu int.
function_ex1.dart
int sum(int a, int b)  {
  return a + b;
}
void main()  {
   var result  = sum(100, 200); // 300
   print('result = $result');  
}
Ví dụ: Hàm greeting chấp nhận một tham số kiểu String và không trả về gì cả.
function_ex2.dart
void greeting(String name)  {
   var s = 'Hello $name';
   print(s);
}
void main()  {
   // Call the function:
   greeting('Tom'); // Hello Tom
}

3. Closure (Bao đóng)

Trong ngôn ngữ lập trình Dart, Closure (bao đóng) là một hàm đặc biệt.
  • Giống như hàm, Closure là một khối lệnh với các tham số và có thể trả về một giá trị hoặc không trả về gì cả.
  • Khác với hàm, Closure không có tên. Nhưng bạn có thể định danh cho nó thông qua một biến.
Xem bài viết chi tiết về Closure:

4. Tham số tuỳ chọn

Như đã đề cập ở trên, Dart không cho phép các hàm cùng tên, nhưng một hàm có thể bao gồm các tham số tuỳ chọn, chúng phải là các tham số đặt tại cuối cùng trong danh sách các tham số.
Cú pháp:
return_type function_name(typeM argM, typeN argN, [typeP? argP, typeQ? argQ]) {  
     // statement(s)  
}
Hoặc cú pháp - Tham số tuỳ chọn với giá trị mặc định:
return_type function_name(typeM argM, typeN argN,
                          [typeP? argP = defaultValueP, typeQ? argQ]) {  
     // statement(s)  
}
Ví dụ:
function_optional_args_ex1.dart
String concat(String s1, String s2, [String? s3]) {
  if (s3 != null) {
    return s1 + s2 + s3;
  }
  return s1 + s2;
}
double sum(double v1, double v2, [double? v3, double? v4]) {
  return v1 + v2 + (v3 ?? 0) + (v4 ?? 0);
}
void main() {
  String result1 =  concat('One', 'Two');
  print('result1: $result1');
  String result2 =  concat('One', 'Two', 'Three');
  print('result2: $result2');
 
  double value1 =  sum(1, 2, 3, 4);
  print('value1: $value1');
  double value2 = sum(1, 2, 3);
  print('value2: $value2');
  double value3 = sum(1, 2);
  print('value3: $value3');
}
Output:
result1: OneTwo
result2: OneTwoThree
value1: 10.0
value2: 6.0
value3: 3.0

5. Tham số tuỳ chọn được đặt tên

Các tham số tuỳ chọn được đặt tên (Optional Named Parameters) là các tham số được đặt trong cặp dấu ngặc { } và đặt tại cuối cùng trong danh sách các tham số của hàm. Tất cả các tham số này đều có giá trị mặc định.
Cú pháp:
return_type function_name(typeM argM, typeN argN,
                                   {typeP argP = defaultValueP, typeQ argQ = defaultValueQ}){  
     // statement(s)  
}
Ví dụ:
function_optional_named_args_ex1.dart
String concatAndTrim(String s1, String s2, {bool trimLeft = true, bool trimRight = true}) {
  var s = s1 + s2;
  if (trimLeft && trimRight) {
    return s.trim();
  } else if (trimLeft) {
    return s.trimLeft();
  } else if (trimRight) {
    return s.trimRight();
  }
  return s;
}
void main() {
  var s1 = '  One  ';
  var s2 = '  Two  ';

  var result1 = concatAndTrim(s1, s2); // trim left and right
  print('result1: -->$result1<-- (Trim left and right)');

  var result2 = concatAndTrim(s1, s2, trimLeft: false); // trim right only
  print('result2: -->$result2<-- (Trim right only)');

  var result3 = concatAndTrim(s1, s2, trimRight: false); // trim left only
  print('result3: -->$result3<-- (Trim left only)' );

  var result4 =
      concatAndTrim(s1, s2, trimLeft: false, trimRight: false); // no trim
  print('result4: -->$result4<!-- (No Trim)');
}
Output:
result1: -->One    Two<-- (Trim left and right)
result2: -->  One    Two<-- (Trim right only)
result3: -->One    Two  <-- (Trim left only)
result4: -->  One    Two  <!-- (No Trim)