Dart Fundamental
Kita telah belajar bagaimana membuat aplikasi sederhana “Hello, World!” menggunakan Dart.
Pada modul ini kita akan mempelajari konsep-konsep dasar pada Dart.
Beberapa topik yang akan kita pelajari antara lain variabel, tipe data, operator, hingga functions.
Comments
Sebelum mulai mengembangkan aplikasi yang lebih kompleks, ada satu hal penting lagi yang perlu kita tahu, yaitu instruksi kepada komputer untuk mengabaikan bagian dari suatu program.
Kode yang ditulis dalam suatu program tetapi tidak dijalankan oleh komputer disebut “comments.”
Sebuah komentar akan dilewatkan ketika proses kompilasi, sehingga tidak akan memengaruhi alur program yang kita tulis. Komentar bisa digunakan sebagai dokumentasi yang menjelaskan kode yang kita tulis.
Terdapat tiga jenis komentar yang bisa digunakan pada Dart. Pertama adalah single-line comment atau komentar satu baris yang diawali dengan tanda // dan berakhir pada akhir baris tersebut.
- // Single line comment
Selanjutnya ada multi-line comment di mana kita bisa menuliskan beberapa baris komentar. Komentar ini dimulai dari tanda /* dan diakhiri dengan */.
- /*
- multi
- line
- comment
- */
Kemudian terakhir adalah documentation comment. Komentar ini adalah single-line comment atau multi-line comment yang diawali dengan /// atau /**.
Di dalam documentation comment, kompiler Dart akan mengabaikan semua teks kecuali yang tertutup dalam kurung siku ([]).
Di dalam kurung siku kita dapat memasukkan referensi dari nama kelas, variabel, atau fungsi. Berikut ini adalah contoh penggunaan komentar:
- import 'package:Belajar_Dart/Belajar_Dart.dart' as Belajar_Dart;
- /// Fungsi [main] akan menampilkan 2 output
- /// Output pertama menampilkan teks dan output kedua menampilkan hasil perkalian pada library [Belajar_Dart]
- void main(List<String> arguments) {
- // Mencetak Hello Dart! Dart is great. pada konsol
- print('Hello Dart! Dart is great.');
- // Testing documentation comment with [].
- print('6 * 7 = ${Belajar_Dart.calculate()}');
- }
- /*
- output:
- Hello Dart! Dart is great.
- 6 * 7 = 42
- */
Jika Anda menggunakan IDE lalu menekan Ctrl dan mengarahkan ke teks di dalam kurung siku, maka Anda akan dapat klik dan mengarah ke kode referensinya.
Menulis komentar pada kode adalah praktik yang baik. Namun perlu diperhatikan, “Kode yang baik memiliki banyak komentar, sementara kode yang buruk memerlukan banyak komentar.”
Variables
Ketika menulis sebuah program, kita memberi tahu komputer cara memproses informasi seperti mencetak teks ke layar atau melakukan operasi perhitungan.
Untuk lebih memudahkan penggunaan dan pemanggilan data ini maka kita bisa memanfaatkan variabel.
Variabel bisa dibayangkan sebagai sebuah kotak atau wadah yang menyimpan nilai. Di dalam komputer variabel ini disimpan di dalam memori komputer.
Setiap variabel memiliki nama yang dapat kita panggil dan gunakan.
Pada Dart kita mendefinisikan sebuah variabel dengan keyword var.
- var greetings = 'Hello Dart!';
Perhatikan tanda sama dengan (=) di atas. Simbol tersebut dikenal dengan assignment operator.
Kode di atas berarti kita memasukkan nilai ‘Hello Dart!’ ke dalam sebuah kotak atau variabel yang bernama greetings. Proses assignment nilai ke variabel ini disebut inisialisasi.
Selanjutnya mari coba tampilkan nilai variabel ini ke konsol. Ubah kode fungsi main Anda menjadi seperti berikut:
- void main() {
- var greetings = 'Hello Dart!';
- print(greetings);
- }
Pada contoh kode di atas kita memasukkan data berupa teks ke dalam variabel. Lalu, bagaimana dengan data numerik atau berupa angka? Tentu saja bisa. Anda cukup menginisialisasi variabel dengan nilai angka.
- var myAge = 20;
- print(myAge);
Lalu bagaimana jika kita ingin membuat variabel namun tidak ingin langsung menginisialisasinya?
Misalnya Anda ingin menunggu beberapa operasi selesai lalu menginisialisasinya ke dalam variabel.
Proses ini disebut dengan deklarasi variabel. Deklarasi variabel akan menyimpan nama dan ruang di dalam memori tanpa memberikan nilai. Anda dapat menginisialisasi nilai setelah deklarasi sesuai dengan kebutuhan Anda.
- var myAge;
- myAge = 20;
- print(myAge);
Sekarang cobalah comment kode inisialisasi variabel di atas lalu jalankan programnya, apa yang terjadi?
Apakah konsol Anda menampilkan null? Setiap deklarasi variabel akan memberikan nilai default berupa null. Ini berarti variabel tersebut belum terinisialisasi atau bisa dibilang variabel Anda tidak memiliki nilai atau null.
Data Types
Pada materi sebelumnya kita telah mempelajari tentang variabel yang dapat menyimpan nilai.
Jadi bagaimana komputer membedakan antara variabel yang bernilai angka atau teks? Dan kenapa penting untuk bisa membedakannya?
Dart memiliki banyak tipe data yang mewakili jenis data yang dapat kita gunakan dan bagaimana data tersebut dioperasikan.
Dengan tipe data, komputer dapat menghindari operasi yang tidak mungkin serta bisa menghasilkan bug, misalnya seperti perkalian karakter alfabet atau mengubah angka menjadi kapital.
Dart adalah bahasa yang mendukung type inference. Ketika Anda mendeklarasikan variabel dengan var, Dart akan secara otomatis menentukan tipe datanya. Misalnya :
- var greetings = 'Hello Dart!'; // String
- var myAge = 20; // integers
Komputer akan tahu bahwa variabel greetings memiliki nilai berupa String atau teks dan variabel myAge bernilai angka atau integers meskipun kita tidak mendefinisikannya secara eksplisit.
Anda tetap bisa mendeklarasikan tipe data variabel secara eksplisit untuk menghindari kebingungan dan memudahkan proses debugging.
- String greetings = 'Hello Dart!';
- int myAge = 20;
Beberapa tipe data yang didukung oleh Dart antara lain:
Tipe | Deskripsi | Contoh |
---|---|---|
int | Integer (bilangan bulat) | 5, -7, 0 |
double | Bilangan desimal | 3.14, 18.0, -12.12 |
num | Bilangan bulat dan bilangan desimal | 5, 3.14, -99.00 |
bool | Boolean | true, false |
String | Teks yang terdiri dari 0 atau beberapa karakter | ‘Dicoding’, ‘Y’, ‘’ |
List | Daftar nilai | [1, 2, 3], [‘a’, ‘b’, ‘c’] |
Map | Pasangan key-value | {“x”: 4, “y”: 10} |
dynamic | Tipe apa pun |
Dart mendukung type inference, menariknya ketika kita mendeklarasikan variabel tanpa melakukan inisialisasi, variabel akan memiliki tipe dynamic.
Karena sebuah variabel bernilai dynamic bisa berisi tipe apa pun, maka tidak ada masalah jika kita mengubah nilai di dalamnya.
- var x; // dynamic
- x = 7;
- x = 'Dart is great';
- print(x);
Kode di atas tetap bisa berjalan dan menampilkan pesan ‘Dart is great’ tanpa ada masalah. Berbeda jika kita menginisialisasi nilai variabel x secara langsung.
Akibatnya, editor akan menampilkan eror karena terjadi perubahan tipe data.
- var x = 7; // int
- x = 'Dart is great'; // Kesalahan assignment
- print(x);
Menerima input pengguna
Selain menampilkan pesan ke konsol, kita juga dapat menerima input pengguna untuk selanjutnya diproses dan ditampilkan. Ini memungkinkan kita dapat membuat aplikasi yang interaktif dengan pengguna.
Untuk bisa menerima input, kita akan menggunakan statement stdin.readLineSync(). Fungsi ini merupakan bagian dari library dart:io, sehingga kita perlu mengimpor library tersebut.
- import 'dart:io';
Kali ini kita akan membuat aplikasi sederhana yang menerima input nama dan usia dari pengguna lalu menampilkan pesan ke konsol. Sebelum melihat kode solusi di bawah bisakah Anda menerjemahkan flowchart berikut menjadi kode aplikasi?
Kode Solusi
Pada persoalan di atas kita perlu menampilkan output, menerima beberapa input, dan menampilkan output lagi sesuai input yang diberikan. Kode yang perlu Anda tulis kurang lebih adalah seperti berikut:
- import 'dart:io';
- void main() {
- stdout.write('Nama Anda : ');
- String name = stdin.readLineSync();
- stdout.write('Usia Anda : ');
- int age = int.parse(stdin.readLineSync());
- print('Halo $name, usia Anda $age tahun');
- }
Jika kode Anda berbeda karena menggunakan print() maka tidak masalah. Statement print() dan stdout.write() memiliki fungsi yang sama yaitu untuk menampilkan suatu objek ke konsol. Yang membedakan adalah print() akan mencetak baris baru setelah menampilkan sesuatu sehingga selanjutnya Anda perlu memasukkan input pada baris baru.
Sementara stdout.write() hanya menampilkan objeknya saja dan ketika ada input atau output baru lagi masih akan ditampilkan di baris yang sama.
Kode baru lain adalah int.parse(). Kita menggunakan kode ini untuk mengkonversi tipe data String menjadi int.
Input yang diambil dari stdin.readLineSync() akan memiliki tipe data berupa String. Sehingga ketika ingin menyimpan dan mengoperasikan input dalam tipe data lain kita perlu melakukan konversi terlebih dahulu.
Numbers
Tipe data angka pada Dart dapat disimpan ke dalam dua jenis: int dan double.
Integers adalah nilai bilangan bulat yang tidak lebih besar dari 64 bit tergantung platform yang digunakan.
Untuk Dart VM variabel integer dapat menyimpan nilai mulai dari -2^63 hingga 2^63 - 1, sementara jika dikompilasi ke JavaScript integer memiliki nilai dari -2^53 sampai 2^53 - 1.
Integer atau bilangan bulat adalah bilangan yang tidak memiliki titik desimal.
Contohnya seperti berikut:
- var number = 2022;
- var hex = 0xDEADBEEF;
Jika sebuah bilangan adalah bilangan desimal, maka bilangan tersebut termasuk tipe data double. Double juga memiliki ukuran sebesar 64 bit. Berikut ini adalah contoh variabel double:
- var decimal = 1.2;
- var pi = 3.14;
Sejak versi Dart 2.1, kita bisa menuliskan tipe data double tanpa menuliskan angka di belakang koma secara literal. Sebelum versi tersebut, kita harus menuliskan bilangan desimal secara literal.
- double withoutDecimal = 7; // Sama dengan double withoutDecimal = 7.0
Int dan double adalah subtipe dari tipe data num. Ketiga tipe data ini dapat kita gunakan untuk melakukan perhitungan dasar seperti penjumlahan, perkalian, hingga menggunakan fungsi seperti abs(), ceil(), floor(), dan banyak fungsi lainnya.
Jika Anda membutuhkan operasi perhitungan namun tidak tersedia pada tiga tipe data ini maka Anda bisa memanfaatkan library dart:math.
Pada materi sebelumnya kita memiliki kebutuhan untuk mengonversi tipe String menjadi int.
Konversi tipe data ini adalah hal yang penting dan kita akan banyak membutuhkannya. Selain konversi String menjadi int, kita juga bisa melakukan konversi double menjadi String atau sebaliknya.
- // String -> int
- var eleven = int.parse('11');
- // String -> double
- var elevenPointTwo = double.parse('11.2');
- // int -> String
- var elevenAsString = 11.toString();
- // double -> String
- var piAsString = 3.14159.toStringAsFixed(2); // String piAsString = '3.14'
Strings
Kita telah banyak menggunakan String pada materi-materi sebelumnya dan seperti kita tahu, String digunakan untuk menyimpan data dalam bentuk teks. String pada Dart dapat didefinisikan dengan menggunakan tanda petik satu maupun petik dua.
- String singleQuote = 'Ini adalah String';
- String doubleQuote = "Ini juga String";
Anda dapat menggunakan tanda petik secara bergantian, khususnya jika Anda memiliki teks yang mengandung tanda petik.
- print('"What do you think of Dart?" he asked');
Lalu bagaimana jika teks kita memiliki kedua tanda petik ini?
- print('"I think it's great!" I answered confidently');
Tentunya kode di atas akan menghasilkan eror. Solusinya, gunakanlah backslash (\) untuk mengurangi ambiguitas dalam tanda petik.
Mekanisme ini juga dikenal dengan nama escape string. Sehingga kode di atas akan menjadi seperti berikut:
- print('"I think it\'s great!" I answered confidently');
Backslash sebelum tanda petik ini akan mengatakan kepada Dart bahwa itu hanyalah tanda petik dan tidak boleh ditafsirkan sebagai pembatas string.
Selain tanda petik, backslash juga berguna untuk mengabaikan simbol lain yang menimbulkan ambigu di dalam string, contohnya seperti backslash itu sendiri.
- print("Windows path: C:\\Program Files\\Dart");
Fitur lain dari String adalah String interpolation di mana kita bisa memasukkan nilai dari variabel atau expression ke dalam string. Interpolation ini bisa kita terapkan dengan simbol $.
- var name = 'Messi';
- print('Hello $name, nice to meet you.');
- print('1 + 1 = ${1 + 1}');
Jika Anda perlu menampilkan harga dalam dollar, maka apa yang akan Anda lakukan? Yup, backslash akan memberitahu Dart mana tanda $ sebagai interpolation atau sebagai mata uang. Selain itu Anda juga menggunakan cara seperti berikut:
- print(r'Dia baru saja membeli komputer seharga $1,000.00');
Huruf ‘r’ sebelum String akan memberitahu Dart untuk menganggap String sebagai raw, yang berarti akan mengabaikan interpolation.
Selain itu, kita juga bisa menambahkan sebuah Unicode ke dalam String. Pada Dart Unicode ini dikenal dengan runes.
Unicode mendefinisikan nilai numerik unik untuk setiap huruf, angka, dan simbol yang digunakan dalam semua sistem penulisan dunia. Cara umum untuk mengekspresikan unicode adalah \uXXXX, di mana XXXX adalah nilai heksadesimal 4 digit.
Misalnya karakter hati (♥) adalah \u2665.
- print('Hi \u2665');
- /*
- output :
- Hi ♥
- */
Booleans
Setelah angka dan teks, ada satu tipe data utama lagi yang penting untuk dipelajari, yaitu boolean.
Nama boolean ini diambil dari nama seorang matematikawan asal Inggris yang bernama George Boole. Beliau dikenal karena penciptaan aljabar boolean, yakni cabang aljabar di mana nilai variabel selalu benar atau salah.
Boolean pada Dart dideklarasikan dengan kata kunci bool. Sesuai dengan penjelasan di atas, variabel boolean hanya bisa menyimpan dua nilai, yaitu true dan false.
- bool alwaysTrue = true;
- var alwaysFalse = false;
- var notTrue = !true;
- bool notFalse = !false;
Tanda ! di atas disebut dengan operator “not” atau “bang”. Operator ini berfungsi untuk menegasikan nilai boolean, sederhananya membalik nilai boolean. Misalnya !true sama saja bernilai false.
Kita akan banyak menggunakan boolean dalam pengembangan aplikasi untuk operasi perbandingan dan juga pengondisian aplikasi.
- if(true) {
- print("It's true");
- } else {
- print("It's False");
- }
Operators
Istilah operator dipinjam dari matematika dengan pengertian yang sedikit berbeda. Pada Dart operator menginstruksikan komputer untuk melakukan operasi.
Sebenarnya kita telah menerapkan beberapa contoh operator pada materi sebelumnya. Sebagai contoh operator assignment (=) yang kita gunakan untuk inisialisasi nilai variabel.
- var firstNumber = 4;
Pada kode di atas kita menginstruksikan komputer untuk memasukkan nilai 4 ke dalam variabel firstNumber.
Operator aritmatika
Contoh operator lain yang telah Anda lihat adalah operator aritmatika yang digunakan untuk operasi seperti penjumlahan atau perkalian. Lihatlah contoh kode berikut:
- var firstNumber = 4;
- var secondNumber = 13;
- var sum = 4 + 13;
- print(sum);
- /*
- Output :
- 17
- */
Dart mendukung operator aritmatika umum sebagai berikut:
Operator | Deskripsi |
---|---|
+ | Penjumlahan |
- | Pengurangan |
* | Perkalian |
/ | Pembagian |
~/ | Pembagian, mengembalikan nilai int |
% | Modulo atau sisa hasil bagi |
- print(5 + 2); // int add = 7
- print(5 - 2); // int subtract = 3
- print(5 * 2); // int multiply = 10
- print(5 / 2); // double divide = 2.5
- print(5 ~/ 2); // int intDivide = 2
- print(5 % 2); // int modulo = 1
Operator aritmatika pada pemrograman memiliki aturan yang sama dengan matematika, di mana perkalian dan pembagian akan didahulukan sebelum penjumlahan atau pengurangan.
- print(2 + 4 * 2); // output: 10
Jika Anda ingin melakukan operasi penjumlahan terlebih dahulu, gunakan tanda kurung atau parentheses.
- print((1 + 3) * (4 - 2)); // output: 8
Selain itu Dart mendukung increment dan decrement. Contohnya adalah seperti berikut:
- var a = 0, b = 5;
- a++;
- b--;
- print(a); // output = 1
- print(b); // output = 4
Expression a++ di atas dapat diartikan dengan a = a + 1. Komputer akan mengambil nilai dari a kemudian menambahkan 1 lalu memasukkannya kembali ke variabel a. Bentuk increment lainnya adalah seperti berikut:
- var c = 0;
- c += 5; // c = c + 5 atau c = 0 + 5
- print(c); // output 5
Operator ini juga bisa digunakan pada operator aritmatika lain seperti perkalian dan pembagian.
- var d = 2;
- d *= 3; // d = d * 3 atau d - 2 * 3
- print(d); // output = 6
Operator perbandingan
Dart juga mendukung operasi perbandingan untuk membandingkan nilai-nilai yang dijadikan sebagai operands. Berikut ini adalah contoh operator perbandingan pada Dart:
Operator | Deskripsi |
---|---|
== | Sama dengan |
!= | Tidak sama dengan |
> | Lebih dari |
< | Kurang dari |
>= | Lebih dari sama dengan |
<= | Kurang dari sama dengan |
Operator perbandingan ini akan mengembalikan nilai dalam bentuk boolean.
- if (2 <= 3) {
- print('Ya, 2 kurang dari sama dengan 3');
- } else {
- print(‘Anda salah’);
- }
- /*
- Output:
- Ya, 2 kurang dari sama dengan 3
- */
Operator logika
Kita juga dapat menggabungkan ekspresi boolean atau membaliknya dengan operator logika. Operator ini meliputi:
Operator | Deskripsi |
---|---|
|| | OR |
&& | AND |
! | NOT |
Kita telah membahas operator NOT atau bang pada materi boolean.
Sementara itu operator OR atau AND digunakan untuk menguji logika dari beberapa nilai boolean.
Operator AND akan menghasilkan nilai true jika semua operand-nya bernilai true, sedangkan OR jika salah satu saja dari operand bernilai true maka operator akan mengembalikan nilai true. Contohnya seperti kode berikut:
- if (2 < 3 && 2 + 4 == 5) {
- print('Untuk mencetak ini semua kondisi harus benar');
- } else {
- print('2 kurang dari 3, tapi 2 + 4 tidak sama dengan 5, maka ini akan tampil');
- }
- if (false || true || false) {
- print('Ada satu nilai true');
- } else {
- print('Jika semuanya false, maka ini akan tampil');
- }
- /*
- Output:
- 2 kurang dari 3, tapi 2 + 4 tidak sama dengan 5, maka ini akan tampil
- Ada satu nilai true
- */
Exceptions
Sebuah aplikasi yang sudah berjalan mungkin mengalami eror dan crash. Kondisi eror pada saat aplikasi berjalan (runtime) ini dikenal dengan exception. Ketika exception terjadi aplikasi akan dihentikan dan program setelahnya juga tidak akan dieksekusi.
Salah satu contoh exception yang mungkin terjadi adalah pada aplikasi kalkulator. Di mana menurut prinsip matematika kita tidak bisa membagi bilangan lain dengan bilangan nol (0).
- var a = 7;
- var b = 0;
- print(a ~/ b);
Coba jalankan kode di atas. Anda akan mendapatkan eror seperti berikut:
Unhandled exception:
IntegerDivisionByZeroException
#0 int.~/ (dart:core-patch/integers.dart:24:7)
#1 main (file:///home/dicoding/Playground/dart/Belajar%20Dart/bin/main.dart:24:11)
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:305:32)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
IntegerDivisionByZeroException
#0 int.~/ (dart:core-patch/integers.dart:24:7)
#1 main (file:///home/dicoding/Playground/dart/Belajar%20Dart/bin/main.dart:24:11)
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:305:32)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
Sebagai developer, tentunya menjadi tugas kita untuk memastikan aplikasi tetap berjalan bagaimana pun kondisinya, termasuk mengatasi ketika terjadi exception. Lantas bagaimana?
Untuk menangani exception, mari gunakan try dan catch. Pindahkan kode yang berpeluang menimbulkan exception ke dalam blok try.
- try {
- var a = 7;
- var b = 0;
- print(a ~/ b);
- }
Kode di atas masih belum lengkap karena di dalam sebuah blok try ada kode yang diasumsikan berpeluang menjadi exception sehingga perlu ditangani.
Pada eror sebelumnya telah diketahui bahwa exception yang terjadi adalah IntegerDivisionByZeroException. Sehingga kita bisa memanfaatkan keyword on untuk mengatasi ketika exception tersebut terjadi.
- try {
- var a = 7;
- var b = 0;
- print(a ~/ b);
- } on IntegerDivisionByZeroException {
- print('Can not divide by zero.');
- }
Nah, kita telah berhasil membuat program kita aman dari crash ketika berusaha membagi bilangan dengan nol. Namun bagaimana dengan exception lainnya yang belum kita ketahui?
Pada Dart sendiri telah tersedia beberapa exception seperti IOException, FormatException, dsb. Untuk menangani exception yang tidak diketahui secara spesifik, kita bisa menggunakan keyword catch setelah blok try.
- try {
- var a = 7;
- var b = 0;
- print(a ~/ b);
- } catch(e) {
- print('Exception happened: $e');
- }
Kode catch membutuhkan satu parameter yang merupakan objek exception. Kita dapat mencetak exception tersebut ke layar untuk menampilkan exception apa yang terjadi. Output kode di atas adalah:
- Exception happened: IntegerDivisionByZeroException
Selain itu, kita juga dapat menambahkan satu parameter lagi di dalam catch yang merupakan objek stack trace. Dari stack trace ini kita bisa melihat detail exception dan di baris mana exception tersebut terjadi.
- try {
- var a = 7;
- var b = 0;
- print(a ~/ b);
- } catch(e, s) {
- print('Exception happened: $e');
- print('Stack trace: $s');
- }
- /*
- Output :
- Exception happened: IntegerDivisionByZeroException
- Stack trace: #0 int.~/ (dart:core-patch/integers.dart:24:7)
- #1 main (file:///home/dicoding/Playground/dart/Belajar%20Dart/bin/main.dart:25:13)
- #2 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:305:32)
- #3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
- */
Blok catch dapat digabungkan dengan on. Catch akan menangkap apabila tidak ada exception yang memenuhi blok on yang terpasang.
Finally
Selain try, on, dan catch, ada satu blok lagi yang ada dalam mekanisme exception handling, yaitu finally. Blok finally akan tetap dijalankan tanpa peduli apa pun hasil yang terjadi pada blok try-catch.
- try {
- var a = 7;
- var b = 0;
- print(a ~/ b);
- } catch(e, s) {
- print('Exception happened: $e');
- print('Stack trace: $s');
- } finally {
- print('This line still executed');
- }
Posting Komentar