Entry API และค่าเริ่มต้น
อัปเดตค่าอย่างสะดวกเป็นธรรมชาติ
Entry API และค่าเริ่มต้น เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
เหตุผลที่ใช้ Entry API
บ่อยครั้งคุณต้องการอัปเดตค่าหากมีคีย์อยู่ หรือแทรกค่าเริ่มต้นหากไม่มีคีย์นั้น
การทำเช่นนี้ด้วย get แล้วตามด้วย insert ค่อนข้างยุ่งยาก ส่วน API entry ทำได้อย่างเรียบร้อยในขั้นตอนเดียว
entry คืนค่าช่องจัดเก็บ
การเรียก entry(key) จะให้ตัวจัดการตำแหน่งของคีย์นั้นในแผนที่
จากตัวจัดการนี้ คุณจะเลือกได้ว่าจะทำอะไร: เติมค่าเริ่มต้น หรือแก้ไขค่าที่มีอยู่
use std::collections::HashMap;
fn main() {
let mut m: HashMap<&str, i32> = HashMap::new();
m.entry("a").or_insert(0);
println!("{}", m["a"]);
}or_insert
or_insert(default) จะแทรกค่าเริ่มต้นเฉพาะเมื่อไม่มีคีย์นั้น จากนั้นคืนค่าการอ้างอิงแบบเปลี่ยนแปลงได้ไปยังค่า
หากมีคีย์อยู่แล้ว ค่าเริ่มต้นจะถูกละเว้น และคุณจะได้ค่าที่มีอยู่
use std::collections::HashMap;
fn main() {
let mut m = HashMap::new();
m.insert("a", 10);
m.entry("a").or_insert(99);
m.entry("b").or_insert(99);
println!("a={}, b={}", m["a"], m["b"]);
}การเปลี่ยนค่าผ่านการอ้างอิง
เนื่องจาก or_insert คืนค่าการอ้างอิงแบบเปลี่ยนแปลงได้ คุณจึงเปลี่ยนค่าได้ทันที
ใช้ * เพื่อถอดการอ้างอิงแล้วอัปเดตค่าโดยตรง นี่คือหัวใจของการนับ
use std::collections::HashMap;
fn main() {
let mut m = HashMap::new();
let count = m.entry("hits").or_insert(0);
*count += 1;
*count += 1;
println!("hits = {}", m["hits"]);
}การนับในลูป
รูปแบบคลาสสิกคือ สำหรับแต่ละรายการ ให้หาช่องจัดเก็บ กำหนดค่าเริ่มต้นเป็นศูนย์ แล้วเพิ่มค่าขึ้นหนึ่ง
วิธีนี้นับจำนวนครั้งที่สิ่งต่าง ๆ ปรากฏได้ โดยใช้ตรรกะเพียงหนึ่งบรรทัดต่อรายการ
use std::collections::HashMap;
fn main() {
let mut counts = HashMap::new();
for c in "hello".chars() {
*counts.entry(c).or_insert(0) += 1;
}
println!("l appears {} times", counts[&'l']);
}or_insert_with
เมื่อค่าเริ่มต้นสร้างได้มีค่าใช้จ่ายสูง ให้ใช้ or_insert_with เมธอดนี้รับคลอเชอร์ที่ทำงานเฉพาะเมื่อไม่มีคีย์
วิธีนี้หลีกเลี่ยงการสร้างค่าที่คุณอาจไม่จำเป็นต้องใช้
use std::collections::HashMap;
fn main() {
let mut m: HashMap<&str, Vec<i32>> = HashMap::new();
m.entry("nums").or_insert_with(Vec::new).push(1);
m.entry("nums").or_insert_with(Vec::new).push(2);
println!("{:?}", m["nums"]);
}and_modify
and_modify จะเรียกใช้คลอเชอร์กับค่าเฉพาะเมื่อมีคีย์อยู่แล้ว
เชื่อมต่อกับ or_insert เพื่อจัดการทั้งสองกรณี: แก้ไขเมื่อมีคีย์อยู่ มิฉะนั้นให้แทรกค่าเริ่มต้น
use std::collections::HashMap;
fn main() {
let mut m = HashMap::new();
m.insert("x", 5);
m.entry("x").and_modify(|v| *v += 10).or_insert(0);
m.entry("y").and_modify(|v| *v += 10).or_insert(1);
println!("x={}, y={}", m["x"], m["y"]);
}or_default
หากชนิดของค่ามี Default เช่น 0 สำหรับจำนวนเต็ม หรือ Vec ว่าง or_default จะนำค่านั้นมาใช้
นี่เป็นรูปแบบย่อของ or_insert(Default::default())
use std::collections::HashMap;
fn main() {
let mut m: HashMap<&str, i32> = HashMap::new();
*m.entry("score").or_default() += 7;
println!("score = {}", m["score"]);
}การสร้างรายการแยกตามคีย์
API ของ entry มีประโยชน์อย่างมากเมื่อจัดกลุ่มรายการไว้ในเวกเตอร์
สำหรับแต่ละคีย์ ให้ใช้ Vec ว่างเป็นค่าเริ่มต้นในครั้งแรก จากนั้นใช้ push เพิ่มข้อมูลลงในเวกเตอร์ที่มีอยู่
use std::collections::HashMap;
fn main() {
let mut groups: HashMap<bool, Vec<i32>> = HashMap::new();
for n in [1, 2, 3, 4] {
groups.entry(n % 2 == 0).or_default().push(n);
}
println!("evens: {:?}", groups[&true]);
}เหตุใดจึงไม่ใช้ get + insert
การใช้ get แยกจากนั้นจึงใช้ insert จะค้นหาคีย์สองครั้ง และทำให้ตัวตรวจสอบการยืมทำงานได้ยาก
API ของ entry ค้นหาเพียงครั้งเดียวและมอบการอ้างอิงที่ปลอดภัยเพียงรายการเดียวให้คุณ จึงเร็วกว่าและสะอาดกว่า
การนำทุกอย่างมารวมกัน
ในที่นี้ การนับและค่าเริ่มต้นทำงานร่วมกันเพื่อค้นหาว่าคำที่ไม่ซ้ำกันแต่ละคำเริ่มต้นด้วยตัวอักษรใดบ้างและมีจำนวนเท่าไร
สังเกตรูปแบบการนับในบรรทัดเดียวที่กำลังทำงาน
use std::collections::HashMap;
fn main() {
let words = ["ant", "art", "bee"];
let mut by_first: HashMap<char, i32> = HashMap::new();
for w in words {
*by_first.entry(w.chars().next().unwrap()).or_insert(0) += 1;
}
println!("a: {}", by_first[&'a']);
}ตรวจสอบความเข้าใจ
คุณต้องการนับ chars โดยค้นหาเพียงครั้งเดียวต่อ char
สรุปทบทวน
API entry ช่วยให้คุณแทรกหรืออัปเดตข้อมูลได้ด้วยการค้นหาเพียงครั้งเดียว
คุณใช้ or_insert, or_insert_with, or_default และ and_modify เพื่อนับรายการและสร้างรายการแยกตามคีย์ได้อย่างเป็นระเบียบ
คำถามที่พบบ่อย
บทเรียน “Entry API และค่าเริ่มต้น” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “Entry API และค่าเริ่มต้น” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “Entry API และค่าเริ่มต้น”
อัปเดตค่าอย่างสะดวกเป็นธรรมชาติ คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “Entry API และค่าเริ่มต้น” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม
ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สร้าง HashMap
- Entry API และค่าเริ่มต้น
- ทำงานกับ HashSet
- การนับและการจัดกลุ่ม