# ปูพื้น Dart ให้พอเขียน Flutter ตอนที่ 1

#Dev#Dart#Flutter

ในส่วนของบทความนี้จะเริ่มจากพื้นฐานมากๆ (ถ้าเคยเขียนโปรแกรมอยู่แล้วอ่านผ่านๆไปก็ได้) ซึ่งผมจะเอาข้อมูลโดยส่วนใหญ่มาจาก Dart Tour (opens new window) แล้วตัดส่วนเฉพาะเท่าที่จำเป็นมาครับ

Tips

สามารถใช้ Dart Pad (opens new window) ในการทดลองเขียนได้ เพื่อเพิ่มความเข้าใจ

Header

# ตัวอย่างโปรแกรม

// ส่วนของการประกาศฟังก์ชัน
printInteger(int aNumber) {
  print('The number is $aNumber.'); // แสดงข้อความออกทางหน้าจอ
}

// โปรแกรมจะเริ่มทำงานจากฟังก์ชัน main เสมอ
main() {
  var number = 42; // การประกาศตัวแปร และกำหนดค่าเริ่มต้น
  printInteger(number); // เรียกใช้ฟังก์ชันที่ชื่อ printInteger
}

ภาษา Dart ก็เหมือนกับภาษาเขียนโปรแกรมทั่วๆไป โดยมีตัวแปรเป็นแบบ Static Typing ที่จะต้องมีการกำหนดชนิดของตัวแปรก่อนใช้ สำหรับใครที่เคยเรียนรู้ภาษาอื่นๆมาก่อน เช่นภาษา C, C++ หรือ Java ก็จะสามารถทำความเข้าใจได้อย่างรวดเร็ว เพราะมีพื้นฐานที่เหมือนๆกัน

// คือ คอมเมนต์ สิ่งที่ต่อหลัง // จะไม่ถูกรันคำสั่ง มีไว้เพื่ออธิบายสิ่งต่างๆในโปรแกรมของเรา

int (Integer) คือ ชนิดตัวแปรแบบตัวเลขจำนวนเต็ม...ในภาษา Dart มีการกำหนดชนิดตัวแปรไว้ให้เบื้องต้น เช่น int, string (ตัวอักษร หรือประโยค), List (รายการของตัวแปร เช่น รายการของตัวเลขจำนวนเต็ม), bool (ค่าความจริง มีได้สองค่าคือเป็นจริง กับ เป็นเท็จ)

print(‘...’) คือ คำสั่งสำหรับการแสดงข้อความออกทางหน้าจอ โดยข้อความของเราจะอยู่ภายใน ... หรือ ... ก็ได้ เป็นข้อมูลชนิด string

main() คือ สิ่งที่ต้องมีในทุกโปรแกรม เมื่อเราเปิดโปรแกรมนี้โปรแกรมจะเริ่มต้นรันที่บรรทัดภายในฟังก์ชัน main โดยเนื้อหาของฟังก์ชันจะอยู่ภายในเครื่องหมาย { และ }

var คือ การประกาศใช้ตัวแปรแบบไม่ต้องกำหนดชนิดเอง โดยจะอ้างอิงจากค่าที่เรากำหนดให้ตอนประกาศ
ตัวอย่างการใช้งาน เช่น

var a = 42;
var b = 'ทดสอบ';
var c = true;

a จะเป็นตัวแปรชนิด int
b จะเป็นตัวแปรชนิด string
c จะเป็นตัวแปรชนิด bool

; (Semi-colon) คือ ตัวจบประโยค เหมือนกับ . ในภาษาอังกฤษ เมื่อเราสั่งคำสั่งใดๆจะลงท้ายด้วย ;

# ค่าเริ่มต้น (Default Value)

เมื่อเราประกาศตัวแปร แต่ไม่กำหนดค่า ตัวแปรเราจำมีค่าเป็น null หรือว่างเปล่า เช่น

int number; // ตัวแปรชื่อ number จะเก็บค่า null

# การใช้ Final และ Const

บางครั้งตัวแปรของเราอาจจะไม่มีการเปลี่ยนค่า คือเก็บค่าไหนก็จะใช้ค่านั้นตลอดไป เราสามารถใช้ final หรือ const ได้ เช่น

final name = 'Intception'; // ใช้แทน var
// หรือ
final string name = 'Intception';

const brand = 'I';
// หรือ
const string brand = 'I';

โดยความต่างระหว่าง final และ const นั่นคือ const จะถูกแปรคำสั่งตั้งแต่ตอน Compiled ซึ่งเป็นขั้นตอนในระหว่างในการแปลง Code ของเราให้เป็นภาษาเครื่อง ยกตัวอย่าง

const pi = 3.14;
const double area = pi * 3 * 3; // area จะถูกคำนวณค่า pi * 3 * 3 แล้วเก็บผลลัพธ์ไว้ตั้งแต่ Compiled
final double area2 = pi * 3 * 3; // area2 จะต้องถูกคำนวณใหม่ทุกครั้งที่มีการประกาศ

Tips

double เป็นชนิดตัวแปรแบบตัวเลขที่มีทศนิยม

# Built-in types

ในภาษา Dart จะมีชนิดตัวแปรเบื้องต้นให้เราใช้ได้ตามรายการ ดังนี้

  • Numbers หรือ ตัวเลขต่างๆ
  • Strings หรือ ข้อความ Unicode 16-bit
  • Booleans หรือ ค่าความจริง
  • Lists หรือ รายการข้อมูล หรืออาจจะเรียกว่า Arrays
  • Sets หรือ เซต เหมือนกับที่เรียนในวิชาคณิตศาสตร์นี่แหละ
  • Maps หรือ ข้อมูลที่เก็บในรูปแบบคู่ Key: Value
  • Runes หรือ ตัวอักษรแบบเดี่ยวๆ Unicode 32-bit ช่างมันไม่น่าจะค่อยได้ใช้บ่อย
  • Symbols ช่างมันไปแล้วกัน 🤣

# Numbers

ตัวเลขในภาษา Dart ง่ายมากไม่ต้องเลือกเยอะ

  • int เก็บตัวเลขที่เป็นจำนวนเต็ม
var x = 1;
var hex = 0xDEADBEEF;
int z = 1.8; // แม้เราจะกำหนดค่าเป็น 1.8 ก็ตาม แต่เวลาเก็บก็จะเป็น int คือ 1
  • double เก็บตัวเลขที่เป็นทศนิยม
var y = 1.1;
var exponents = 1.42e5;
double z = 1; // แม้เราจะกำหนดค่าเป็น 1 ก็ตาม แต่เวลาเก็บก็จะเป็น double คือ 1.0

และถ้าเราต้องการแปลงค่าไปมาระหว่างข้อความ กับตัวเลข

// String -> int
var one = int.parse('1');
assert(one == 1);

// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);

// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');

// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');

# Strings

เราสามารถใช้ได้ทั้ง ' (Single Quote) และ " (Double Quote) ในการสร้างข้อความ (ซึ่งหลังจากนี้ผมจะขอเรียกว่า string นะครับ)

var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";

และเราสามารถใช้ตัวแปรด้านใน string ได้ดังตัวอย่างนี้

var pageName = 'Intception Hideout';
var pageViews = 8;
print('เพจของผมชื่อ $pageName หรือชื่อ ${pageName.toUpperCase()} มีคนดูอยู่ $pageViews คน')
// ผลลัพธ์: เพจของผมชื่อ Intception Hideout หรือชื่อ INTCEPTION HIDEOUT มีคนดูอยู่ 8 คน

โดยเราจะเห็นว่า เราสามารถแทรกตัวแปรได้โดยใช้ $ชื่อตัวแปร หรือ ${ชื่อตัวแปร/การทำงานบางอย่าง} โดยถึงแม้ว่าตัวแปรเราจะเป็นชนิด int ก็ยังสามารถแทรกเข้าไปได้ เพราะเบื้องหลังมีการแปลง pageViews เป็น string ก่อน (คือมีการเรียก .toString())

และเรายังสามารถต่อ string 2 ตัวเข้าด้วยกันโดยใช้ + Operator ได้อีกด้วย

print('Dart is ' + 'Awesome!');
// ผลลัพธ์: Dart is Aweosome!

ถ้าเราต้องการเขียนข้อความหลายๆบรรทัดเราสามารถใช้ \n หรือ """ หรือ ''' ได้ครับ เช่น

print('This\nis\nmultiline\nstring');
print("""This
is
multiline
string""");
print('''This
is
multiline
string''');
/*ผลลัพธ์ที่ได้เหมือนกัน คือ
This
is
multiline
string
*/

หากเราต้องการ Raw String หรือพิมพ์อย่างไงก็ได้อย่างงั้นใช้ r"" เช่น

print(r"This\nis\nmultiline\nstring");
// ผลลัพธ์: This\nis\nmultiline\nstring

# Booleans

อันนี้ไม่มีอะไรมากครับ มีแค่ค่าความจริง true หรือ false

// ตรวจสอบว่า string ว่างเปล่าหรือไม่
var fullName = '';
assert(fullName.isEmpty);

// ตรวจสอบว่าเป็นค่า 0 หรือไม่
var hitPoints = 0;
assert(hitPoints == 0);

// ตรวจสอบว่าเป็น null หรือไม่ ซึ่ง null คือค่าว่างเวลาที่เราประกาศตัวแปรแต่ไม่ได้กำหนดค่าให้ ตัวแปรจะมีค่าเป็น null
var unicorn;
assert(unicorn == null);

// ตรวจสอบว่าเป็น NaN (Not a number) หรือไม่
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);

Tips

เราสามารถใช้ assert ในการทดสอบแอปของเราได้ โปรแกรมจะหยุดทำงานทันทีถ้าสิ่งที่อยู่ใน assert เป็นค่า false โดย assert จะทำงานใน debug mode เท่านั้น

คำเตือน

จากตัวอย่างข้างต้นเราไม่สามารถใช้ assert(fullName) โดยตรงได้ เพราะสิ่งที่ assert หรือ if (ซึ่งเราจะเรียนในบทถัดๆไป) ต้องการนั้นคือ boolean เท่านั้น

# Lists

รายการหรือกลุ่มของข้อมูลขั้นพื้นฐานซึ่งในภาษาอื่นๆอาจจะเรียกมันว่า array (หรือกลุ่มข้อมูลแบบมีลำดับ) ตัวอย่างเช่น

var list1= [1, 2, 3]; // ก็เขียนเหมือนๆภาษาอื่นนี่แหละครับ
// หรือ
List<int> list2 = [1, 2, 3];

คำเตือน

List ของ Dart นั้นมีชนิดตัวแปรที่เก็บ ดังนั้นเราไม่สามารถใส่ [1, 2, '3'] ได้ครับ สิ่งที่อยู่ใน List จะต้องเป็นชนิดข้อมูลเดียวกันทั้งหมด

และหากเราต้องการข้อมูลของ List ตัวแรกนั้น เราสามารถทำได้โดย

var list = ['A', 'B', 'C'];
print(list[0]); // แสดงผลข้อมูลตัวแรกสุดก็คือ 'A'
print(list[list.length - 1]); // แสดงผลข้อมูลตัวท้ายก็คือ 'C'

เราสามารถกำหนดค่าของสมาชิกของ List ได้โดย

var list = ['A', 'B', 'C'];
list[1] = 'D';  // เปลี่ยนค่าสมาชิกลำดับที่ 1
print(list);    // ['A', 'D', 'C']

ใน Dart ตังแต่เวอร์ชัน 2.3 ขึ้นไป
เราสามารถใช้ ... นำหน้า List เพื่อดึงค่าไปใส่อีก List ได้ เช่น

var list = ['A', 'B', 'C'];
var list2 = ['D', ...list]; // list2 จะมีค่าเป็น ['D', 'A', 'B', 'C']

จากตัวอย่าง list ด้านบนอาจจะเป็น null ก็ได้ ซึ่งถ้าเราใช้ ... กับ null โปรแกรมจะเกิด Error ขึ้นได้ เราสามารถใช้ ...? ในการป้องการความเป็น null ของตัวแปรได้ เช่น

var list;
var list2 = ['D', ...?list]; // list2 จะมีค่าเป็น ['D']

ใน Dart ตังแต่เวอร์ชัน 2.3 ขึ้นไป เราสามารถใช้ เงื่อนไข if หรือ for ใน List ก็ได้ เช่น

var nav = [
  'Home',
  'Furniture',
  'Plants',
  if (promoActive) 'Outlet'
];

ถ้าตัวแปร promoActive เป็นจริง เราจะได้ค่า ['Home', 'Furniture', 'Plants', 'Outlet'] แต่ถ้าเป็นเท็จ เราจะได้ค่า ['Home', 'Furniture', 'Plants']

# Sets

เซต คือ ชุดหรือกลุ่มข้อมูลที่ไม่มีการเรียงลำดับ และจะไม่มีทางซ้ำกัน

var data1 = {'Dart', 'Flutter', 'Javascript', 'Flutter'}; // data จะเก็บค่า {'Dart', 'Flutter', 'Javascript'} และข้อมูลจะไม่มีการเรียงลำดับ
หรือ
Set<String> data2 = {'Dart', 'Flutter', 'Javascript', 'Flutter'};

ถ้าเราต้องการสร้าง Set เปล่าๆเราสามารถทำได้โดย

var data1 = <String>{};
// หรือ
Set<String> data2 = {};

var data3 = {}; // อันนี้สิ่งที่เราจะได้ไม่ใช่ Set แต่จะเป็น Map แทน

โดยเราสามารถเพิ่มข้อมูลเข้าไปในเซตได้โดยใช้ add() หรือ จากเซตอื่นด้วย addAll()

var data1 = {'Dart', 'Flutter', 'Javascript', 'Flutter'};
var data2 = {'Python'};
data2.add('Ruby');   // {'Python', 'Ruby'}
data2.addAll(data1); // {'Python', 'Ruby', 'Dart', 'Flutter', 'Javascript', 'Flutter'}

ใช้ .length เพื่อหาขนาดของเซต

var data1 = {'Dart', 'Flutter', 'Javascript', 'Flutter'};
print(data1.length); // 4

และใน Dart เวอร์ชัน 2.3 ก็มี ... และ ...? ให้ใช้ได้เหมือนกันกับ List เลยครับ

# Maps

เป็นกลุ่มข้อมูลแบบกำหนด Key และ Value โดย Key จะมีได้แค่ Key เดียวเท่านั้น แต่ Value จะซ้ำกันยังไงก็ได้

var gifts = {
  // Key:  Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};  // Map<String, String>

var nobleGases = {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};  // Map<int, String>

คำเตือน

เช่นเดียวกับ List และ Set เราไม่สามารถใส่ข้อมูลแบบผสมชนิดตัวแปรได้

และในขณะเดียวกันเราสามารถเขียนอีกแบบให้ได้ผลลัพธ์เหมือนตัวอย่างด้านบนได้ด้วยวิธีนี้

var gifts = Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';

var nobleGases = Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';

เราสามารถอ่านสมาชิกของ Map ได้โดย

var gifts = {'first': 'partridge'};
print(gifts['first']);  // partridge
print(gifts['fifth']);  // ถ้าใน Map ไม่มี Key ผลลัพธ์จะเป็น null

ใช้ .length เพื่อหาขนาดของ Map

var gifts = {
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
}; 
print(gifts.length); // 3

และใน Dart เวอร์ชัน 2.3 ก็มี ... และ ...? ให้ใช้ได้เหมือนกันกับ List และ Set เลยครับ


ก็จบลงไปแล้วครับสำหรับ Part 1 สำหรับ Part หน้าเราจะมาเริ่มกันในเรื่องการเขียน Functions ในภาษา Dart กันครับ 😁

# แบบฝึกหัด


ข้อที่ 1 data จะเก็บค่าอะไร?
var data;

ข้อที่ 2 โปรแกรมด้านล่างสามารถทำงานได้หรือไม่?
var myString = 'My name is Conan';
myString = 48;

ข้อที่ 3 false กับ null เหมือนกันหรือไม่?

ข้อที่ 4 ผลลัพธ์ที่ได้จะเป็นเท่าไร?
var myVar = [1, 2, 100];
print(myVar[1]);

ข้อที่ 5 ผลลัพธ์ที่ได้จะเป็นเท่าไร?
var myVar = [1, 2, 100];
print(myVar.length);

อัปเดตเมื่อ: 1 ปีที่แล้ว