From i Into
Część sekcji Programowanie obiektowe ścieżki Rust w Coddy. Lekcja 57 z 61.
Konwersja między typami to częste zadanie w Rust. Cecha From zapewnia ustandaryzowany sposób określania, jak można utworzyć jeden typ z innego. Gdy zaimplementujesz From, automatycznie otrzymasz cechę Into za darmo.
Aby zaimplementować From, określasz, jak skonstruować swój typ z innego typu:
struct Meters(f64);
struct Kilometers(f64);
impl From<Kilometers> for Meters {
fn from(km: Kilometers) -> Self {
Meters(km.0 * 1000.0)
}
}
Teraz możesz dokonać konwersji za pomocą funkcji from lub metody into:
let distance = Kilometers(5.0);
// Jawne użycie From
let m1 = Meters::from(distance);
// Użycie Into (działa, ponieważ zaimplementowano From)
let distance = Kilometers(3.0);
let m2: Meters = distance.into();
Metoda into() wymaga adnotacji typu, ponieważ Rust musi wiedzieć, na jaki typ konwertujesz. Ten wzorzec jest szczególnie przydatny, gdy masz pomocnicze struktury, które trzeba przekonwertować na główne typy, na przykład gdy konwertujesz dane konfiguracyjne na zainicjalizowany obiekt albo przekształcasz surowe dane wejściowe w zwalidowaną strukturę.
Wyzwanie
ŁatwyZbudujmy system konwersji temperatur za pomocą cechy From! Utworzysz dwa typy temperatur: Celsius i Fahrenheit, a następnie zaimplementujesz konwersje między nimi przy użyciu standardowych cech konwersji Rust.
Rozmieścisz kod w dwóch plikach:
temperature.rs: Zdefiniuj dwie publiczne struktury newtype,CelsiusiFahrenheit, z których każda opakowuje wartość typuf64. Zaimplementuj cechęFrom, aby konwertowaćCelsiusnaFahrenheitprzy użyciu wzoru:fahrenheit = celsius × 1.8 + 32.0. Dodaj też do każdej struktury metodęvalue, która zwraca wartość wewnętrzną typuf64.main.rs: Dołącz moduł temperatur i pokaż oba sposoby konwersji. Utwórz wartośćCelsiusna podstawie podanego wejścia, a następnie przekonwertuj ją naFahrenheitza pomocąFahrenheit::from(). Utwórz kolejną wartośćCelsiusi przekonwertuj ją za pomocą metody.into(). Wyświetl oba wyniki.
Wzór konwersji ze stopni Celsjusza na Fahrenheita jest następujący: pomnóż przez 1.8 i dodaj 32. Pamiętaj, że zaimplementowanie From<Celsius> for Fahrenheit automatycznie i bez dodatkowego wysiłku udostępnia cesze Into<Fahrenheit> dla typu Celsius!
Obie temperatury są wyświetlane jako liczby całkowite: rzutuj każdą wartość f64 za pomocą as i64, co ucina część dziesiętną w kierunku zera. Dlatego wejście 36.6 jest wyświetlane jako 36C, a temperatura 97.88 stopni Fahrenheita, na którą jest konwertowane, jest wyświetlana jako 97F. Nic nie jest zaokrąglane w górę.
Wynik powinien wyświetlać obie konwersje w tym formacie:
From: {celsius1}C = {fahrenheit1}F
Into: {celsius2}C = {fahrenheit2}FNa przykład dla wejść 0 i 100:
From: 0C = 32F
Into: 100C = 212FA dla wejść 25 i -40:
From: 25C = 77F
Into: -40C = -40FOtrzymasz dwa wejścia: pierwszą wartość w stopniach Celsjusza (parsowaną jako f64) oraz drugą wartość w stopniach Celsjusza (parsowaną jako f64).
Spróbuj swoich sił
mod temperature;
use temperature::{Celsius, Fahrenheit};
fn main() {
// Odczytaj dane wejściowe
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: Utwórz wartość Celsius na podstawie celsius1
// TODO: Przelicz ją na Fahrenheit za pomocą Fahrenheit::from()
// TODO: Utwórz kolejną wartość Celsius na podstawie celsius2
// TODO: Przelicz ją na Fahrenheit za pomocą .into()
// TODO: Wypisz wyniki w formacie:
// From: {celsius1}C = {fahrenheit1}F
// Into: {celsius2}C = {fahrenheit2}F
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Metody i zachowanie
Wprowadzenie do bloków implementacjiParametr selfMetody modyfikująceFunkcje powiązaneWiele bloków implementacjiŁańcuchowe wywoływanie metodPowtórzenie — działania na prostokącie4Projekt: Wirtualne zwierzątko
Definiowanie zwierzątkaKarmienie zwierzątka7Standardowe cechy
Cecha DebugCecha DisplayClone i CopyCechy równościPowtórka – punkt do wydrukowania10Projekt: System dokumentów
Trait DrawKomponent tekstowy2Hermetyzacja i moduły
Podstawy modułówSłowo kluczowe publicPola prywatneGetterySetteryPodsumowanie — bezpieczna skrytka5Typy generyczne
Struktury generyczneMetody generyczneWiele typów generycznychFunkcje generycznePodsumowanie – punkt współrzędnych8Cechy jako ograniczenia
Składnia ograniczeń cechWiele ograniczeńKlauzula whereZwracanie typów z użyciem cechPodsumowanie — generyczna drukarka11Wzorce projektowe w Rust
Wzorzec NewtypeKompozycjaTrait DropFrom i IntoPodsumowanie — atrapowy inteligentny wskaźnik3Zaawansowane typy wyliczeniowe
Typy wyliczeniowe z danymiMetody typów wyliczeniowychDopasowywanie wariantów danychTyp wyliczeniowy Option — powtórzeniePodsumowanie — typ wyliczeniowy Shape6Definiowanie cech
Czym jest cecha?Implementowanie cechImplementacje domyślneNadpisywanie wartości domyślnychCechy z parametramiPowtórzenie — odtwarzacz multimedialnyPoćwicz samodzielnie: Kompilator Rust online