เป็นเรื่องที่ดีที่ Go มีDuration
ประเภท - การมีหน่วยงานที่กำหนดไว้อย่างชัดเจนสามารถป้องกันปัญหาในโลกแห่งความจริง
และเนื่องจากกฎประเภทที่เข้มงวดของ Go คุณจึงไม่สามารถคูณ Duration ด้วยจำนวนเต็มได้ - คุณต้องใช้การส่งนักแสดงเพื่อคูณประเภทสามัญ
/*
MultiplyDuration Hide semantically invalid duration math behind a function
*/
func MultiplyDuration(factor int64, d time.Duration) time.Duration {
return time.Duration(factor) * d // method 1 -- multiply in 'Duration'
// return time.Duration(factor * int64(d)) // method 2 -- multiply in 'int64'
}
เอกสารอย่างเป็นทางการแสดงให้เห็นถึงการใช้วิธีการ # 1:
ในการแปลงจำนวนเต็มหน่วยเป็นระยะเวลาให้คูณ:
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
แต่แน่นอนว่าการคูณระยะเวลาด้วยระยะเวลาไม่ควรสร้างระยะเวลา - ที่ไร้สาระบนใบหน้าของมัน ในกรณีที่จุด 5 มิลลิวินาทีครั้งที่ 5 6h56m40s
มิลลิวินาทีผลิต ความพยายามในการทำตาราง 5 วินาทีจะส่งผลให้เกิดการโอเวอร์โฟลว์
อย่างไรก็ตามการเป็นint64
ตัวแทนDuration
ในหน่วยนาโนวินาที"จำกัด ระยะเวลาที่สามารถนำเสนอได้มากที่สุดเป็นประมาณ 290 ปี"และสิ่งนี้บ่งชี้ว่าDuration
เช่นint64
นั้นจะถือว่าเป็นค่าที่ลงชื่อ: (1<<(64-1))/(1e9*60*60*24*365.25) ~= 292
และนั่นคือวิธีการนำไปใช้จริง:
// A Duration represents the elapsed time between two instants
// as an int64 nanosecond count. The representation limits the
// largest representable duration to approximately 290 years.
type Duration int64
ดังนั้นเนื่องจากเรารู้ว่าการเป็นตัวแทนพื้นฐานของDuration
คือการint64
แสดงตัวระหว่างint64
และDuration
เป็น NO-OP ที่สมเหตุสมผล - ต้องการเพียงเพื่อให้เป็นไปตามกฎภาษาเกี่ยวกับประเภทการผสมและไม่มีผลต่อการดำเนินการคูณที่ตามมา
หากคุณไม่ชอบการคัดเลือกนักแสดงด้วยเหตุผลของความบริสุทธิ์ให้ฝังไว้ในการเรียกใช้ฟังก์ชันตามที่ฉันได้แสดงไว้ด้านบน
rand.Seed(time.Now().Unix())