Dart is a true object-oriented language, so even functions are objects and have a type, Function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
main() { print(isOld(50)); print(isNotOld(50)); print(isFifty(50)); print(isSixty(60)); } bool isOld(int old) { return old > 50; } isNotOld(old) { return old <= 50; } bool isFifty(int old) => old == 50; bool isSixty(int old) => old == 60 ? true : false; |
บรรทัดที่ 8 : การประกาศฟังก์ชัน
บรรทัดที่ 12 : การประกาศฟังก์ชัน แบบไม่ระบุชนิดของตัวแปร และชนิดของ returnt type
บรรทัดที่ 16 : การประกาศฟังก์ชันแบบ shorthand syntax
บรรทัดที่ 18 : การประกาศฟังก์ชันแบบ shorthand syntax ร่วมกับการใช้ conditional expression
Optional positional parameters
ใส่พารามิเตอร์ใน []
ทำให้กลายเป็น optional parameters
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
main() { assert(say('Bob', 'Howdy') == 'Bob says Howdy'); assert(say('Bob', 'Howdy', 'smoke signal') == 'Bob says Howdy with a smoke signal'); } String say(String from, String msg, [String device]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } return result; } |
Default parameter values
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
main() { assert(say('Bob', 'Howdy') == 'Bob says Howdy with a carrier pigeon'); assert(say('Bob', 'Howdy', 'iPhone') == 'Bob says Howdy with a iPhone'); } String say(String from, String msg, [String device = 'carrier pigeon', String mood]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } if (mood != null) { result = '$result (in a $mood mood)'; } return result; } |
กำหนด List
และ Map
เป็น default value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
main() { doStuff(); } void doStuff( {List<int> list = const [1, 2, 3], Map<String, String> gifts = const { 'first': 'paper', 'second': 'cotton', 'third': 'leather' }}) { print('list: $list'); print('gifts: $gifts'); } |
จะได้
1 2 |
list: [1, 2, 3] gifts: {first: paper, second: cotton, third: leather} |
The main() function
1 2 3 4 5 6 7 |
void main(List<String> arguments) { print(arguments); assert(arguments.length == 2); assert(int.parse(arguments[0]) == 1); assert(arguments[1] == 'test'); } |
รันทาง command line จะไม่แสดง error ของ assert
1 2 |
D:\Project\dart\my_dart\bin>dart my_dart.dart [] |
ต้องใส่ --enable-asserts
ด้วย ก็จะแสดง error ของ assert
1 2 3 4 5 6 7 8 9 10 |
D:\Project\dart\my_dart\bin>dart --enable-asserts my_dart.dart [] Unhandled exception: 'file:///D:/Project/dart/my_dart/bin/my_dart.dart': Failed assertion: line 5 pos 10: 'arguments.length == 2': is not tru e. #0 _AssertionError._doThrowNew (dart:core/runtime/liberrors_patch.dart:40:39) #1 _AssertionError._throwNew (dart:core/runtime/liberrors_patch.dart:36:5) #2 main (file:///D:/Project/dart/my_dart/bin/my_dart.dart:5:10) #3 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:287:32) #4 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12) |
ทีนี้ใส่พารามิเตอร์ไป 2 ตัวคือ 1 test
ก็จะผ่านละ ไม่ error
1 2 |
D:\Project\dart\my_dart\bin>dart --enable-asserts my_dart.dart 1 test [1, test] |
Pass a function as a parameter to another function
1 2 3 4 5 6 7 8 9 10 |
void main() { var list = [1, 2, 3]; // Pass printElement as a parameter. list.forEach(printElement); } void printElement(int element) { print(element); } |
จะได้
1 2 3 |
1 2 3 |
ลองเขียนฟังก์ช้นด้วย shorthand syntax
1 2 3 4 5 6 |
void main() { var list = [1, 2, 3]; list.forEach(printElement); } void printElement(int element) => print(element * 10); |
ฟังก์ชันซ้อนอยู่ใน ฟังก์ชันได้
1 2 3 4 5 6 |
void main() { void printElement(int element) => print(element * 20); var list = [1, 2, 3]; list.forEach(printElement); } |
Assign a function to a variable
1 2 3 4 |
void main() { var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!'; assert(loudify('hello') == '!!! HELLO !!!'); } |
Anonymous functions
1 2 3 4 5 6 |
void main() { var list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); }); } |
หรือ
1 2 3 4 |
void main() { var list = ['apples', 'bananas', 'oranges']; list.forEach((item) => print('${list.indexOf(item)}: $item')); } |
จะได้
1 2 3 |
0: apples 1: bananas 2: oranges |
ขอบเขตของตัวแปร (Lexical scope)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
bool topLevel = true; void main() { var insideMain = true; void myFunction() { var insideFunction = true; void nestedFunction() { var insideNestedFunction = true; assert(topLevel); assert(insideMain); assert(insideFunction); assert(insideNestedFunction); } } } |
Lexical closures
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/// Returns a function that adds [addBy] to the /// function's argument. Function makeAdder(num addBy) { return (num i) => addBy + i; } void main() { // Create a function that adds 2. var add2 = makeAdder(2); // Create a function that adds 4. var add4 = makeAdder(4); assert(add2(3) == 5); assert(add4(3) == 7); } |
Testing functions for equality
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
void foo() {} // A top-level function class A { static void bar() {} // A static method void baz() {} // An instance method } void main() { var x; // Comparing top-level functions. x = foo; assert(foo == x); // Comparing static methods. x = A.bar; assert(A.bar == x); // Comparing instance methods. var v = A(); // Instance #1 of A var w = A(); // Instance #2 of A var y = w; x = w.baz; // These closures refer to the same instance (#2), // so they're equal. assert(y.baz == x); // These closures refer to different instances, // so they're unequal. assert(v.baz != w.baz); } |
Return values
ปกติฟังก์ชันจะคืนค่า ถ้าไม่กำหนด return ก็จะได้คืนค่าเป็น null
ยกเว้นเรากำหนด void ไว้หน้าฟังก์ชัน ฟังก์ชันก็จะไม่คืนค่า
1 2 3 4 5 6 7 |
main() { foo() {} assert(foo() == null); void bar() {} //assert(bar() == null); // Uncommenting this causes an error. } |
Link
- A Tour of the Dart Language – Functions