Menu
CoddyTech

From và Into

Thuộc phần Lập trình hướng đối tượng trong hành trình Rust của Coddy. Bài học 57 trên 61.

Chuyển đổi giữa các kiểu dữ liệu là việc thường gặp trong Rust. Trait From cung cấp cách chuẩn hóa để định nghĩa cách tạo một kiểu dữ liệu từ kiểu dữ liệu khác. Khi triển khai From, bạn tự động có trait Into mà không mất thêm công sức.

Để triển khai From, bạn định nghĩa cách tạo kiểu của mình từ một kiểu khác:

struct Meters(f64);
struct Kilometers(f64);

impl From<Kilometers> for Meters {
    fn from(km: Kilometers) -> Self {
        Meters(km.0 * 1000.0)
    }
}

Giờ đây, bạn có thể chuyển đổi bằng hàm from hoặc phương thức into:

let distance = Kilometers(5.0);

// Sử dụng From một cách tường minh
let m1 = Meters::from(distance);

// Sử dụng Into (hoạt động vì From đã được triển khai)
let distance = Kilometers(3.0);
let m2: Meters = distance.into();

Phương thức into() cần có chú thích kiểu dữ liệu vì Rust cần biết bạn đang chuyển đổi sang kiểu nào. Cách làm này đặc biệt hữu ích khi bạn có các struct hỗ trợ cần chuyển đổi sang những kiểu dữ liệu chính, chẳng hạn như chuyển dữ liệu cấu hình thành một đối tượng đã khởi tạo hoặc biến đổi đầu vào thô thành một cấu trúc đã được xác thực.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống chuyển đổi nhiệt độ bằng trait From! Bạn sẽ tạo hai kiểu nhiệt độ, Celsius và Fahrenheit, rồi triển khai chuyển đổi giữa chúng bằng các trait chuyển đổi tiêu chuẩn của Rust.

Bạn sẽ sắp xếp code trong hai tệp:

  • temperature.rs: Định nghĩa hai struct newtype công khai, Celsius và Fahrenheit, mỗi struct bọc một giá trị f64. Triển khai trait From để chuyển đổi Celsius thành Fahrenheit theo công thức: fahrenheit = celsius × 1.8 + 32.0. Đồng thời, thêm phương thức value vào mỗi struct để trả về giá trị bên trong dưới dạng f64.
  • main.rs: Đưa module nhiệt độ vào và minh họa cả hai cách chuyển đổi. Tạo một giá trị Celsius từ đầu vào đã cho, sau đó chuyển đổi thành Fahrenheit bằng Fahrenheit::from(). Tạo một giá trị Celsius khác và chuyển đổi bằng phương thức .into(). In ra cả hai kết quả.

Công thức chuyển đổi từ Celsius sang Fahrenheit là: nhân với 1.8 rồi cộng 32. Hãy nhớ rằng khi triển khai From<Celsius> for Fahrenheit, bạn sẽ tự động có trait Into<Fahrenheit> trên Celsius mà không cần làm gì thêm!

Cả hai nhiệt độ đều được in dưới dạng số nguyên: ép kiểu mỗi giá trị f64 bằng as i64, thao tác này loại bỏ phần thập phân theo hướng về 0. Vì vậy, đầu vào 36.6 sẽ được in thành 36C, còn nhiệt độ 97.88 độ Fahrenheit mà giá trị đó chuyển đổi thành sẽ được in thành 97F. Không có giá trị nào được làm tròn lên.

Đầu ra của bạn cần hiển thị cả hai phép chuyển đổi theo định dạng sau:

From: {celsius1}C = {fahrenheit1}F
Into: {celsius2}C = {fahrenheit2}F

Ví dụ, với đầu vào 0 và 100:

From: 0C = 32F
Into: 100C = 212F

Và với đầu vào 25 và -40:

From: 25C = 77F
Into: -40C = -40F

Bạn sẽ nhận hai đầu vào: giá trị Celsius thứ nhất (phân tích thành f64) và giá trị Celsius thứ hai (phân tích thành f64).

Tự làm thử

mod temperature;

use temperature::{Celsius, Fahrenheit};

fn main() {
    // Đọc đầu vào
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let celsius1: f64 = input1.trim().parse().expect("Invalid number");
    
    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let celsius2: f64 = input2.trim().parse().expect("Invalid number");
    
    // TODO: Tạo một giá trị Celsius từ celsius1
    // TODO: Chuyển giá trị đó sang Fahrenheit bằng Fahrenheit::from()
    
    // TODO: Tạo một giá trị Celsius khác từ celsius2
    // TODO: Chuyển giá trị đó sang Fahrenheit bằng .into()
    
    // TODO: In kết quả theo định dạng:
    // From: {celsius1}C = {fahrenheit1}F
    // Into: {celsius2}C = {fahrenheit2}F
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Rust online