เรื่องใส่ id สลับที่กัน
เขียน #rustlang แบบ
(word_id, textunit_id)
วันเดียวพอจำได้หรอก เขียนไปนาน ๆ อาจจะพลาดใส่
(textunit_id, word_id)
ก็ได้
อันนี้ static type อาจจะวืดเพราะทั้ง textunit-id และ word-id ก็เป็น u32 ทั้งคู่ อาจจะแก้แบบนี้สร้าง type มาใหม่เลย WordId กับ TextunitId แต่มันก็เหนื่อยอยู่นะ
ไม่ก็ใช้ struct แทน เช่น
struct WordIdTextunitId {
word_id: u32,
textunit_id: u32,
}
อันนี้เขียนง่ายดี แต่ compiler ไม่ได้ช่วยอะไรมากนะ ก็คือ programmer ก็ดูเอาเมื่อไหร่เขียน
WordIdTextunitId { word_id: textunit_id, textunit_id: word_id }
แบบนี้ก็ผิด โปรแกรมเมอร์เห็นเอง แต่ใส่สลับกัน compiler มันก็ผ่านนะ
แล้วคิดไปติดมามันก็พอกับเขียน Clojure เลย
{:word-id word-id
:textunit-id textunit-id}
แบบนี้ก็ชัดเจนอยู่แล้ว ไม่ต้องประกาศ struct ด้วย หรือจะใช้ defstruct เลยก็ได้
ใน Common Lisp ก็คล้าย ๆ กัน def struct ก็ได้ จะทำเป็น alist ก็ได้
(list (cons :word-id word-id)
(cons :textunit-id textunit-id))
แบบนี้ก็ได้
กลับมา Rust จะจัดหนักแบบ ทำแบบนี้ก็บึ้มอยู่ดี
type WordId = u32;
type TextunitId = u32;
struct WordIdTextUnitId {
word_id: WordId,
textunit_id: TextunitId,
}
fn main() {
let w: WordId = 1;
let t: TextunitId = 2;
let x = WordIdTextUnitId { word_id: t, textunit_id: w};
}
สลับได้ compiler ไม่ช่วยอะไร
แต่ถ้าทำเป็น struct หมดเลย
struct WordId(u32);
struct TextunitId(u32);
struct WordIdTextUnitId {
word_id: WordId,
textunit_id: TextunitId,
}
fn main() {
let w = WordId(1);
let t = TextunitId(2);
let x = WordIdTextUnitId { word_id: t, textunit_id: w};
}
แบบนี้ compiler มันจะช่วยได้รู้แล้วว่าสลับกัน
แต่ก็จะมาเจอว่าผมอยากได้
let v = w + 1;
แบบนี้ทำไง ก็มีวิธีทำหลายทางนะ เพียงแต่มันก็ต้องออกแรง