Daily Archives: 23/10/2017

Rust – Input

Trong phần này chúng ta sẽ tìm hiểu cách đọc dữ liệu.

Module io trong crate std Rust cung cấp rất nhiều các hàm và hỗ trợ đọc/ghi dữ liệu từ dòng dữ liệu tiêu chuẩn của máy tính. Ở đây chúng ta chỉ cần hiểu là chúng ta có thể lấy được những gì gõ từ bàn phím chuột, rồi từ đó có thể ghi lên các thiết bị xuất như màn hình, loa…

Chúng ta sẽ tìm hiểu về các thuật ngữ module và crate sau, trước mắt chúng ta chỉ cần biết là để sử dụng module và crate thì chúng ta sử dụng từ khóa use với tên module ở đầu file. Ví dụ:

use std::io;

fn main() {     
let mut buf = String::new();    
println!("Your name: ");    
io::stdin().read_line(&mut buf);    
println!("Hello, {}", buf);
}

Trong đoạn code trên, chúng ta sử dụng module std:io bằng cách sử dụng câu lệnh use, sau đó chúng ta gọi đến hàm stdin() của module này, hàm này sẽ tạo một đối tượng Stdin, và chúng ta dùng phương thức read_line() để đọc dữ liệu từ bàn phím rồi gán vào biến buf. Chúng ta sẽ tìm hiểu về khái niệm đối tượng và phương thức trong các bài sau.

Khi biên dịch và chạy, chương trình sẽ đọc dữ liệu từ dòng dữ liệu vào từ bàn phím cho đến khi đọc được dữ liệu của phím Enter thì dừng, và do đó chúng ta phải gõ một cái gì đó vào màn hình rồi bấm enter, đoạn code trên sẽ in ra những gì mà chúng ta gõ.

Your name:
Phocode
Hello, Phocode

Ngoài ra khi biên dịch Rust sẽ in một câu cảnh cáo là:

warning: unused `std::result::Result` which must be used

Vì hàm read_line() trả về một đối tượng Result, nên chúng ta nên tận dụng các hàm lấy kết quả của đối tượng này, lớp Result có 2 kiểu kết quả trả về, một là Ok (thành công), hai là Err (lỗi). Để có thể lấy được giá trị của 2 kết quả này thì chúng ta lần lượt gọi tới hàm ok()expect() của đối tượng này. Ví dụ:

use std::io;

fn main() {     
let mut buf = String::new();    
println!("Your name: ");    
io::stdin().read_line(&mut buf).ok().expect("error!");      
println!("Hello, {}", buf);
}

Hàm ok() sẽ chuyển đối tượng Result thành một đối tượng Option, sau đó chúng ta gọi hàm expect() của đối tượng này, hàm này sẽ  trả về giá trị của đối tượng Option, nếu có lỗi thì hàm này sẽ in câu thông báo lỗi mà chúng ta đã truyền vào lên màn hình.

Hiện tại thì đoạn code trên sẽ khó có thể in ra chuỗi bên trong expect() được vì Rust sẽ luôn luôn chờ cho đến khi chúng ta bấm phim enter và bắt đầu đọc, kể cả khi chúng ta không đưa kí tự nào vào, cách duy nhất để kiểm tra hàm expect() là tiến hành đọc từ các dòng dữ liệu khác như file, mạng internet… chúng ta sẽ tìm hiểu về chủ đề này sau.

Ngoài việc đọc các chuỗi bình thường, chúng ta cũng có thể đọc các kiểu dữ liệu khác như số, ví dụ:

use std::io;

fn main() {     
let mut buf = String::new();    
println!("Your birth year: ");      
io::stdin().read_line(&mut buf)
.ok()
.expect("error!");      
let buf_i32: Result<u32, _> = buf.trim().parse();    
println!("Your age in 2017 is {}", 2017 – buf_i32.ok().expect("Error"));
}

Chúng ta cũng đọc một chuỗi như bình thường, sau đó nếu chúng ta, chuyển sang kiểu u32 bằng cách dùng hàm trim() để loại bỏ kí tự enter trong chuỗi, rồi dùng hàm parse() để chuyển sang kiểu dữ liệu khác, ở đây là kiểu Result<u32, _>. Chúng ta sẽ tìm hiểu về cú pháp này sau.

Khi đã có đối tượng Result, chúng ta có thể gọi ok()expect() để lấy ra giá trị u32 gốc và có thể tính toán trên giá trị đó bình thường.

Your birth year:
1993
Your age in 2017 is 24