นี้จะสัมผัสในขณะนี้ในรุ่นที่สองของสนิมโปรแกรมภาษา อย่างไรก็ตามเรามาดูเพิ่มเติมกันดีกว่า
ให้เราเริ่มต้นด้วยตัวอย่างที่ง่ายกว่า
เมื่อใดจึงเหมาะสมที่จะใช้วิธีลักษณะ?
มีหลายวิธีในการเชื่อมโยงล่าช้า :
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 MyStruct
trait MyTrait<Return>
impl
Return