More about printing
Di Rust, Anda bisa mem-print sesuatu dengan cara apapun yang Anda inginkan. Ini adalah hal yang seharusnya diketahui mengenai printing.
Menambahkan \n
akan membuat sebuah new line, dan \t
akan membuat sebuah tab:
fn main() { // Catatan: ini adalah print!, bukan println! print!("\t Start with a tab\nand move to a new line"); }
Ia akan mem-print:
Start with a tab
and move to a new line
Di dalam ""
Anda bisa menulis banyak baris tanpa ada masalah, tapi berhati-hatilah dengan spacing:
fn main() { // Catatan: Setelah menulis baris pertama, Anda perlu memulai lanjutannya pada bagian ujung kiri. // Jika Anda menulis langsung di bawah println!, maka ia akan menambahkan spasi println!("Inside quotes you can write over many lines and it will print just fine."); println!("If you forget to write on the left side, the spaces will be added when you print."); }
Berikut adalah hasil printnya:
Inside quotes
you can write over
many lines
and it will print just fine.
If you forget to write
on the left side, the spaces
will be added when you print.
Jika Anda ingin mencetak karakter seperti \n
(biasa disebut dengan "escape characters"), Anda bisa menambahkan ekstra \
:
fn main() { println!("Here are two escape characters: \\n and \\t"); }
Ini adalah hasilnya:
Here are two escape characters: \n and \t
Terkadang kita menulis terlalu banyak "
dan escape characters, dan menginginkan Rust untuk mengabaikan semua itu. Untuk melakukan hal ini, Anda bisa menambahkan r#
pada bagian awal dan #
pada bagian akhir.
fn main() { println!("He said, \"You can find the file at c:\\files\\my_documents\\file.txt.\" Then I found the file."); // Kita menggunakan \ 5 kali pada baris ini println!(r#"He said, "You can find the file at c:\files\my_documents\file.txt." Then I found the file."#) }
Keduanya akan mencetak kembalian yang sama, namun dengan menggunakan r#
membuat codenya menjadi lebih mudah dibaca oleh kita.
He said, "You can find the file at c:\files\my_documents\file.txt." Then I found the file.
He said, "You can find the file at c:\files\my_documents\file.txt." Then I found the file.
Jika Anda perlu mencetak sebuah #
di dalamnya, maka Anda bisa memulainya r##
dan mengakhirinya dengan ##
. Dan jika Anda memerlukannya lebih dari 1, Anda bisa menambahkan 1 lagi # pada setiap sisinya.
Ini adalah 4 buah contoh yang kita buat:
fn main() { let my_string = "'Ice to see you,' he said."; // single quotes let quote_string = r#""Ice to see you," he said."#; // double quotes let hashtag_string = r##"The hashtag #IceToSeeYou had become very popular."##; // Memiliki 1 buah #, sehingga kita memerlukan ## di setiap sisinya let many_hashtags = r####""You don't have to type ### to use a hashtag. You can just use #.""####; // Memiliki ###, sehingga kita memerlukan #### di setiap sisinya println!("{}\n{}\n{}\n{}\n", my_string, quote_string, hashtag_string, many_hashtags); }
Ini adalah hasil cetakannya:
'Ice to see you,' he said.
"Ice to see you," he said.
The hashtag #IceToSeeYou had become very popular.
"You don't have to type ### to use a hashtag. You can just use #."
r#
memiliki kegunaan lainnya: dengan ini Anda bisa menggunakan keyword (seperti let
, fn
, dsb.) sebagai nama variabel.
fn main() { let r#let = 6; // Nama variabelnya adalah let let mut r#mut = 10; // Nama variabelnya adalah mut }
r#
memiliki kegunaan seperti ini karena versi Rust yang lebih tua memiliki lebih sedikit keyword daripada Rust yang sekarang. Sehingga, dengan r#
Anda bisa menghindari kesalahan dengan penamaan variabel yang mana sebelumnya ia bukan keywords.
Atau mungkin untuk alasan tertentu Anda benar-benar membutuhkan sebuah fungsi yang harus diberi nama return
. Maka Anda bisa menuliskannya seperti ini:
fn r#return() -> u8 { println!("Here is your number."); 8 } fn main() { let my_number = r#return(); println!("{}", my_number); }
Maka hasilnya adalah seperti berikut:
Here is your number.
8
Bisa jadi Anda sama sekali tidak memerlukannya, namun jika Anda benar-benar perlu untuk menggunakan sebuah keyword untuk menjadi sebuah variabel, maka Anda bisa menggunakan r#
.
Jika Anda ingin mencetak nilai byte dari sebuah &str
atau char
, Anda cukup menuliskan b
sebelum stringnya ditulis. Ini bekerja untuk semua karakter ASCII. Ini adalah semua karakter ASCII:
βΊβ»β₯β¦β£β β«βΌβΊβββΌΒΆΒ§β¬β¨ββββββ²βΌ123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Sehingga di saat Anda mem-print code dibawah ini:
fn main() { println!("{:?}", b"This will look like numbers"); }
Beginilah hasilnya:
[84, 104, 105, 115, 32, 119, 105, 108, 108, 32, 108, 111, 111, 107, 32, 108, 105, 107, 101, 32, 110, 117, 109, 98, 101, 114, 115]
Untuk sebuah char
, ini disebut sebagai byte, dan untuk &str
biasanya disebut sebagai byte string.
Anda juga bisa menggunakan b
dan r
bersamaan jika Anda memerlukannya:
fn main() { println!("{:?}", br##"I like to write "#"."##); }
Dan ini adalah hasil printnya [73, 32, 108, 105, 107, 101, 32, 116, 111, 32, 119, 114, 105, 116, 101, 32, 34, 35, 34, 46]
.
Dan ada juga Unicode escape yang akan mencetak karakter Unicode di dalam sebuah string: \u{}
. Untuk mencetak hal tersebut, nilai hexadesimal ditulis di dalam {}
. Berikut adalah contoh singkat tentang bagaimana cara untuk mendapatkan nilai Unicode, dan mencetaknya kembali dengan nilai hexadesimal yang didapatkan.
fn main() { println!("{:X}", 'ν' as u32); // Cast char sebagai u32 untuk mendapatkan nilai hexadesimal println!("{:X}", 'H' as u32); println!("{:X}", 'ε± ' as u32); println!("{:X}", 'γ' as u32); println!("\u{D589}, \u{48}, \u{5C45}, \u{3044}"); // Cetak hexadesimal menggunakan unicode escape \u }
Kita tahu bahwa println!
bisa mencetak sesuatu menggunakan {}
(untuk Display) dan {:?}
(untuk Debug), juga {:#?}
untuk pretty printing. Tapi masih ada banyak cara untuk melakukan print.
Sebagai contoh, jika Anda memiliki reference, Anda bisa menggunakan {:p}
untuk mencetak alamat pointer. Alamat pointer adalah lokasi pada memori komputer Anda.
fn main() { let number = 9; let number_ref = &number; println!("{:p}", number_ref); }
Program di atas akan mencetak 0xe2bc0ffcfc
atau alamat yang lain. Hasilnya akan selalu berbeda setiap saat, tergantung dimana komputer Anda menyimpan data tersebut.
Anda juga bisa mencetak biner, hexadesimal dan oktal seperti berikut:
fn main() { let number = 555; println!("Binary: {:b}, hexadecimal: {:x}, octal: {:o}", number, number, number); }
Hasilnya adalah Binary: 1000101011, hexadecimal: 22b, octal: 1053
.
Anda juga bisa menambahkan angka untuk mengubah urutannya. Variabel pertama akan menjadi index ke-0, selanjutnya di index ke-1, dan seterusnya.
fn main() { let father_name = "Vlad"; let son_name = "Adrian Fahrenheit"; let family_name = "ΘepeΘ"; println!("This is {1} {2}, son of {0} {2}.", father_name, son_name, family_name); }
father_name
ada pada posisi ke-0, son_name
ada pada posisi ke-1, dan family_name
ada pada posisi ke-2. Maka code tersebut akan mencetak This is Adrian Fahrenheit ΘepeΘ, son of Vlad ΘepeΘ
.
Mungkin juga Anda memiliki sebuah string yang sangat rumit untuk dicetak dengan terlalu banyaknya variabel di dalam {}
. Atau mungkin Anda perlu mencetak sebuah variabel lebih dari 1 kali. Itu bisa dilakukan dengan cara menambahkan nama ke dalam {}
:
fn main() { println!( "{city1} is in {country} and {city2} is also in {country}, but {city3} is not in {country}.", city1 = "Seoul", city2 = "Busan", city3 = "Tokyo", country = "Korea" ); }
Hasilnya adalah seperti berikut:
Seoul is in Korea and Busan is also in Korea,
but Tokyo is not in Korea.
Melakukan printing yang begitu kompleks juga sangat memungkinkan dilakukan di Rust jika Anda ingin menggunakannya. Beginilah cara menggunakannya:
{variable:padding alignment minimum.maximum}
Untuk memahami hal ini, perhatikan poin-poin berikut:
- Apakah Anda menginginkan sebuah nama variabel? Tuliskan itu dibagian awal, seperti saat kita menulis {country} pada contoh di atas.
(Kemudian tambahkan sebuah
:
setelahnya jika Anda ingin melakukan hal yang lain) - Apakah Anda menginginkan sebuah padding character? Sebagai contoh, 55 dengan tiga buah "padding zeros" akan terlihat seperti 00055.
- Alignment seperti apa yang diperlukan untuk padding tersebut (left / middle / right)?
- Apakah Anda memerlukan panjang minimum? (cukup tuliskan angkanya)
- Apakah Anda memerlukan panjang maximum? (tuliskan
.
setelah angka minimum beserta dengan angka maximumnya)
Sebagai contoh, kita ingin menulis "a" dengan lima buah karakter γ di bagian kiri dan lima karakter γ di bagian kanan:
fn main() { let letter = "a"; println!("{:γ ^11}", letter); }
Maka inilah hasil cetaknya γ
γ
γ
γ
γ
aγ
γ
γ
γ
γ
. Lihat kembali poin 1) sampai 5) untuk memahami bagaimana compiler membaca format ini.
- Apakah Anda menginginkan nama variabel? Di
{:γ ^11}
tidak ada nama variabel. Tidak ada apapun yang ditulis sebelum:
. - Apakah Anda menginginkan sebuah padding character?
{:γ ^11}
Ya. γ ditulis setelah:
dan memiliki sebuah^
.<
artinya lakukan padding dengan meletakkan karakter disebelah kiri,>
berarti lakukan padding dengan meletakkan karakter disebelah kanan, dan^
artinya karakter akan diletakkan di tengah. - Apakah Anda memerlukan panjang minimum?
{:γ ^11}
Ya: Disitu tertulis angka 11. - Apakah Anda memerlukan panjang maximum?
{:γ ^11}
Tidak: tidak ada.
setelah minimum dan juga angka setelahnya.
Berikut adalah contoh dari berbagai cara untuk melakukan formatting.
fn main() { let title = "TODAY'S NEWS"; println!("{:-^30}", title); // tidak ada nama variabel, pad menggunakan -, letakkan dibagian tengah, dengan panjang 30 karakter let bar = "|"; println!("{: <15}{: >15}", bar, bar); // tidak ada nama variabel, pad menggunakan space, masing-masing 15 karakter di kiri dan juga kanan let a = "SEOUL"; let b = "TOKYO"; println!("{city1:-<15}{city2:->15}", city1 = a, city2 = b); // city1 dan city2 sebagai nama variabel, pad menggunakan -, satu ke kiri, dan satu lagi ke kanan }
Berikut adalah hasil cetaknya:
---------TODAY'S NEWS---------
| |
SEOUL--------------------TOKYO