Rust: алғашқы қадамнан жеке жоспарлау құралына дейін 33-сабақ (барлығы 60)
Сұрақ белгісі: қатені шақырған жерге жеткізу
33-сабақ. Әуелі минут санын оқып, кейін оның жарамдылығын тексеріп, қатенің себебін қайтару.
Мәтін ИИ көмегімен аударылды.
Алдын ала: 12, 14 және 30–32-сабақтар. Ok пен Err шатасса, 32-сабақты қайталаңыз.
Таныс бейне және тірек сызба
Өтінішті қабылдайтын адам алдымен санның жазылғанын, одан кейін оның жарамдылығын тексереді. Алғашқы тексеру өтпесе, кейінгі қадамға бармай, себебін айтып өтінішті кері қайтарады. Result мәнінен кейінгі ? белгісі де осыған ұқсайды: Ok болса, ішіндегі мәнді алып функцияны жалғастырады; Err болса, қатені осы функциядан бірден қайтарады. Мұны қатені жоғарыға жеткізу дейміз. Ұқсатудың шегі: ? хабар ойлап таппайды және қатені түзетпейді; ол Rust түрлерінің ережесімен мәнді қайтарады.
Санды оқу → Ok жалғасады / Err қайтады → нөлді тексеру → Ok не жаңа Err. ? қолданатын функция мұнда Result<u32, String> қайтарады. ? алдындағы өрнек те Result<u32, String> береді, сондықтан қате түрлері сәйкес. return Err(...) — 14-сабақтағы ерте қайту: функция сол жерде аяқталады. Ол нөл туралы жаңа түсіндірме жасайды.
Екі түрлі тексеру
organizer жобасының бұрынғы src/main.rs файлын сақтап, оны толық ауыстырыңыз. Cargo.toml тұрған бумада cargo run орындаңыз. Басқа файл мен тәуелділік өзгермейді. Үш жолдық нәтижені болжаңыз.
parse_number сан жазылған мәтінді өзге мәтіннен ажыратады. checked_minutes санды parse_number(text)? арқылы алады. Қате қайтса, осы функцияның кейінгі жолдары орындалмайды. Сан нөл болса, өзге қате жасалады. Пайдаланушыға нені көрсету керегін main шешеді; тексеру функциялары өздері хабар шығармайды.
fn parse_number(text: &str) -> Result<u32, String> {
match text.parse::<u32>() {
Ok(number) => Ok(number),
Err(_) => Err(String::from("Бүтін сан енгізіңіз")),
}
}
fn checked_minutes(text: &str) -> Result<u32, String> {
let minutes = parse_number(text)?;
if minutes == 0 {
return Err(String::from("Минут нөлден үлкен болуы керек"));
}
Ok(minutes)
}
fn main() {
for text in ["20", "0", "жақында"] {
match checked_minutes(text) {
Ok(minutes) => println!("Қабылданды: {minutes} мин"),
Err(message) => println!("Қате: {message}"),
}
}
}
Қабылданды: 20 мин
Қате: Минут нөлден үлкен болуы керек
Қате: Бүтін сан енгізіңіз
Сан жазылымындағы қате мен оның мағынасындағы қате бөлек қаралды. ? хабарды пәрмен жолына өзі шығармайды: main ішіндегі Err тармағы оны көрсетеді. Кейін бұл тәсіл жоспарлау құралының логикасын пәрмен жолындағы көріністен бөлуге көмектеседі.
? қай жерде жарамды?
? ағымдағы функция қатенің сәйкес түрін қайтара алса қолданылады. Нәтиже түрі жазылмаған fn main() 14-сабақтағы () қайтарады, Err(String) мәнін сыртқа бере алмайды. Келесі бөлек мысал E0277 қатесімен әдейі құрастырылмайды:
fn main() {
let value: Result<u32, String> = Ok(20);
let minutes = value?;
println!("{minutes}");
}
? белгісінің басқа қолданылуы да бар. Әзірше қате түрі бірдей екі Result<u32, String> функциясымен шектелеміз. Қате түрлері бөлек болса, алдын ала үйренілген түрлендіру тәсілі қажет; құрастыру қатесін жоғалту үшін орынсыз .unwrap() қоспаңыз.
Түсінгеніңізді тексеріңіз
?алдындағыOk(20)не істейді?parse_numberErrқайтарса, нөлді тексеру орындала ма?- Пайдаланушыға хабарды кім шығарады?
Жауап: 20 алынып, жұмыс жалғасады; жоқ, қате ертерек қайтады; main. Тірек сызбаны жатқа айтыңыз.
Тапсырма
Міндетті. Мысалдағыдай parse_number мен checked_minutes функцияларын ? қолданып жазыңыз, бірақ Сан енгізіңіз және Минут нөл болмауы керек хабарларын пайдаланыңыз. "15", "0", "көп" мәндерін тексеріңіз. Қабылданды: 15 мин және екі түрлі қате хабары шығуы керек. Тексеру функцияларының ішінде хабар шығармаңыз.
Шекара. Неге "0" мәтіні нөл тексеруіне жетеді, ал "көп" жетпейді?
Ишара
let minutes = parse_number(text)?; жолы Result<u32, String> қайтаратын функцияда тұрады. Содан кейін if minutes == 0 жаңа Err қайтарады.
Талпыныстан кейінгі үлгі жауап
fn parse_number(text: &str) -> Result<u32, String> {
match text.parse::<u32>() {
Ok(number) => Ok(number),
Err(_) => Err(String::from("Сан енгізіңіз")),
}
}
fn checked_minutes(text: &str) -> Result<u32, String> {
let minutes = parse_number(text)?;
if minutes == 0 {
return Err(String::from("Минут нөл болмауы керек"));
}
Ok(minutes)
}
fn main() {
for text in ["15", "0", "көп"] {
match checked_minutes(text) {
Ok(minutes) => println!("Қабылданды: {minutes} мин"),
Err(message) => println!("Қате: {message}"),
}
}
}
Қабылданды: 15 мин
Қате: Минут нөл болмауы керек
Қате: Сан енгізіңіз
Екі функция тексереді, ал main хабарды көрсетеді. ? туралы ресми түсіндірме.
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.