นี้จะสัมผัสในขณะนี้ในรุ่นที่สองของสนิมโปรแกรมภาษา อย่างไรก็ตามเรามาดูเพิ่มเติมกันดีกว่า
ให้เราเริ่มต้นด้วยตัวอย่างที่ง่ายกว่า
เมื่อใดจึงเหมาะสมที่จะใช้วิธีลักษณะ?
มีหลายวิธีในการเชื่อมโยงล่าช้า :
trait MyTrait {
fn hello_word(&self) -> String;
}
หรือ:
struct MyTrait<T> {
t: T,
hello_world: fn(&T) -> String,
}
impl<T> MyTrait<T> {
fn new(t: T, hello_world: fn(&T) -> String) -> MyTrait<T>;
fn hello_world(&self) -> String {
(self.hello_world)(self.t)
}
}
โดยไม่คำนึงถึงกลยุทธ์การนำไปใช้งาน / ประสิทธิภาพใด ๆ ทั้งสองข้อความที่ตัดตอนมาข้างต้นทำให้ผู้ใช้สามารถระบุได้อย่างมีไดนามิกว่าhello_worldควรปฏิบัติอย่างไร
หนึ่งความแตกต่าง (ความหมาย) คือการที่ผู้traitค้ำประกันการใช้งานที่สำหรับประเภทได้รับTการดำเนินการtrait, hello_worldมักจะมีพฤติกรรมเดียวกันในขณะที่structการดำเนินการอนุญาตให้มีพฤติกรรมที่แตกต่างกันในแต่ละตัวอย่างพื้นฐาน
การใช้วิธีจะเหมาะสมหรือไม่ขึ้นอยู่กับลักษณะการใช้งาน!
เมื่อใดจึงเหมาะสมที่จะใช้ประเภทที่เกี่ยวข้อง
เช่นเดียวกับtraitวิธีการข้างต้นประเภทที่เกี่ยวข้องคือรูปแบบของการผูกแบบล่าช้า (แม้ว่าจะเกิดขึ้นในการคอมไพล์) ซึ่งอนุญาตให้ผู้ใช้traitระบุอินสแตนซ์ที่กำหนดว่าจะใช้ประเภทใดแทน ไม่ใช่วิธีเดียว (ดังนั้นคำถาม):
trait MyTrait {
type Return;
fn hello_world(&self) -> Self::Return;
}
หรือ:
trait MyTrait<Return> {
fn hello_world(&Self) -> Return;
}
เทียบเท่ากับการผูกปลายของวิธีการข้างต้น:
- คนแรกบังคับว่าสำหรับสิ่งที่ระบุ
Selfมีหนึ่งเดียวที่Returnเกี่ยวข้อง
- คนที่สองแทนช่วยให้การดำเนินการ
MyTraitสำหรับSelfหลาย ๆReturn
รูปแบบใดเหมาะสมกว่าขึ้นอยู่กับว่าเหมาะสมที่จะบังคับใช้ Unicity หรือไม่ ตัวอย่างเช่น:
Deref ใช้ประเภทที่เกี่ยวข้องเนื่องจากไม่มีความเป็นเอกภาพคอมไพเลอร์จะบ้าคลั่งในระหว่างการอนุมาน
Add ใช้ประเภทที่เกี่ยวข้องเนื่องจากผู้เขียนคิดว่าการกำหนดอาร์กิวเมนต์ทั้งสองจะมีประเภทการส่งคืนเชิงตรรกะ
อย่างที่คุณเห็นในขณะที่Derefเป็นกรณีการใช้งานที่ชัดเจน (ข้อ จำกัด ทางเทคนิค) แต่กรณีของการAddตัดที่ชัดเจนน้อยกว่า: อาจจะสมเหตุสมผลที่i32 + i32จะให้ผลอย่างใดอย่างหนึ่งi32หรือComplex<i32>ขึ้นอยู่กับบริบท? อย่างไรก็ตามผู้เขียนใช้ดุลยพินิจของพวกเขาและตัดสินใจว่าการเพิ่มประเภทการคืนสินค้ามากเกินไปนั้นไม่จำเป็น
จุดยืนส่วนตัวของฉันคือไม่มีคำตอบที่ถูกต้อง อย่างไรก็ตามนอกเหนือจากอาร์กิวเมนต์ unicity ฉันจะพูดถึงว่าประเภทที่เกี่ยวข้องทำให้การใช้ลักษณะง่ายขึ้นเนื่องจากลดจำนวนพารามิเตอร์ที่ต้องระบุดังนั้นในกรณีที่ประโยชน์ของความยืดหยุ่นในการใช้พารามิเตอร์ลักษณะปกติไม่ชัดเจนฉัน แนะนำให้เริ่มด้วยประเภทที่เกี่ยวข้อง
trait/struct MyTrait/MyStructช่วยให้ตรงหนึ่งหรือimpl MyTrait forอนุญาตหลายs เพราะเป็นเรื่องทั่วไป สามารถเป็นประเภทใดก็ได้ โครงสร้างทั่วไปเหมือนกันimpl MyStructtrait MyTrait<Return>implReturn