โดยปกติหากไลบรารีมีประเภททั่วไปFoo<T>ลังแบบดาวน์สตรีมจะไม่สามารถใช้คุณลักษณะได้แม้ว่าจะเป็นTจะเป็นประเภทโลคัลก็ตาม ตัวอย่างเช่น,
( crate_a)
struct Foo<T>(pub t: T)
( crate_b)
use crate_a::Foo;
struct Bar;
// This causes an error
impl Clone for Foo<Bar> {
fn clone(&self) -> Self {
Foo(Bar)
}
}
สำหรับตัวอย่างที่เป็นรูปธรรมที่ทำงานบนสนามเด็กเล่น (นั่นคือให้ข้อผิดพลาด)
use std::rc::Rc;
struct Bar;
// This causes an error
// error[E0117]: only traits defined in the current crate
// can be implemented for arbitrary types
impl Default for Rc<Bar> {
fn default() -> Self {
Rc::new(Bar)
}
}
(สนามเด็กเล่น)
ตามปกตินี้จะช่วยให้ผู้เขียนลังเพิ่มการใช้งาน (ครอบคลุม) ของลักษณะโดยไม่ทำลายลังขาลง เป็นสิ่งที่ยอดเยี่ยมในกรณีที่ไม่แน่ใจในตอนแรกว่าประเภทควรใช้คุณลักษณะเฉพาะ แต่ในภายหลังจะชัดเจนว่าควรใช้ num-traitsยกตัวอย่างเช่นเราอาจจะมีการเรียงลำดับของประเภทตัวเลขบางอย่างที่ตอนแรกไม่ใช้ลักษณะจาก คุณสมบัติเหล่านั้นสามารถเพิ่มได้ในภายหลังโดยไม่จำเป็นต้องเปลี่ยนการแตกหัก
อย่างไรก็ตามในบางกรณีผู้เขียนไลบรารีต้องการให้ลังดาวน์สตรีมสามารถใช้คุณลักษณะได้ด้วยตนเอง นี่คือที่#[fundamental]มาของแอ็ตทริบิวต์เมื่อวางบนชนิดคุณลักษณะใด ๆ ที่ไม่ถูกนำไปใช้ในปัจจุบันสำหรับประเภทนั้นจะไม่ถูกนำมาใช้ เป็นผลให้ลังดาวน์สตรีมสามารถใช้คุณลักษณะสำหรับประเภทนั้นตราบใดที่พารามิเตอร์ type เป็นโลคัล (มีกฎที่ซับซ้อนบางอย่างสำหรับการตัดสินใจว่าพารามิเตอร์ชนิดใดนับรวมอยู่ในนี้) เนื่องจากประเภทพื้นฐานจะไม่ใช้คุณลักษณะที่กำหนดคุณลักษณะนั้นจึงสามารถนำไปใช้ได้อย่างอิสระโดยไม่ก่อให้เกิดปัญหาการเชื่อมโยงกัน
ตัวอย่างเช่นBox<T>มีการทำเครื่องหมาย#[fundamental]ดังนั้นรหัสต่อไปนี้ (คล้ายกับRc<T>รุ่นด้านบน) ใช้งานได้ Box<T>ไม่ใช้Default(เว้นแต่จะมีTการดำเนินการDefault) ดังนั้นเราจึงสามารถสรุปได้ว่ามันจะไม่เกิดขึ้นในอนาคตเพราะBox<T>เป็นพื้นฐาน โปรดทราบว่าการดำเนินการDefaultสำหรับการBarจะทำให้เกิดปัญหาตั้งแต่นั้นมาการดำเนินการอยู่แล้วBox<Bar>Default
struct Bar;
impl Default for Box<Bar> {
fn default() -> Self {
Box::new(Bar)
}
}
(สนามเด็กเล่น)
บนมืออื่น ๆ #[fundamental]ลักษณะนี้ยังสามารถทำเครื่องหมายด้วย สิ่งนี้มีความหมายสองอย่างสำหรับประเภทพื้นฐาน หากประเภทใดไม่ได้ใช้คุณลักษณะพื้นฐานในปัจจุบันก็สามารถสันนิษฐานได้ว่าประเภทนั้นจะไม่ดำเนินการในอนาคต (อีกครั้งยกเว้นการเปลี่ยนแปลงที่ทำลาย) ฉันไม่แน่ใจว่าวิธีนี้ใช้ในการปฏิบัติ ในรหัส (ลิงก์ด้านล่าง) FnMutมีการทำเครื่องหมายพื้นฐานพร้อมด้วยข้อความที่จำเป็นสำหรับ regex (บางอย่างเกี่ยวกับ&str: !FnMut) ฉันไม่พบตำแหน่งที่ใช้ในregexลังไม้หรือหากใช้ที่อื่น
ในทางทฤษฎีหากAddคุณลักษณะนั้นเป็นพื้นฐาน (ซึ่งได้มีการพูดคุยกัน) สิ่งนี้อาจถูกนำมาใช้เพื่อเพิ่มเติมระหว่างสิ่งที่ยังไม่มีอยู่ ตัวอย่างเช่นการเพิ่ม[MyNumericType; 3](จุด) ซึ่งอาจมีประโยชน์ในบางสถานการณ์ (แน่นอนว่าการสร้าง[T; N]พื้นฐานจะอนุญาตสิ่งนี้ด้วย)
ดั้งเดิมประเภทพื้นฐานมี&T, &mut T(ดูที่นี่สำหรับการสาธิตของชนิดดั้งเดิมทั่วไปทั้งหมด) ในไลบรารีมาตรฐานBox<T>และPin<T>ถูกทำเครื่องหมายเป็นพื้นฐาน
ลักษณะพื้นฐานในห้องสมุดมาตรฐานSized, Fn<T>, FnMut<T>, และFnOnce<T>Generator
โปรดทราบว่า#[fundamental]ขณะนี้แอตทริบิวต์ไม่เสถียร ปัญหาการติดตามเป็นปัญหา #
&T,&mut T,*const T,*mut T,[T; N],[T],fnตัวชี้และ tuples และทดสอบพวกเขาทั้งหมด (โปรดบอกฉันว่ารหัสนี้ไม่สมเหตุสมผล) ดูเหมือนว่าการอ้างอิงเป็นประเภทพื้นฐานดั้งเดิมเท่านั้น น่าสนใจ ฉันสนใจที่จะรู้เหตุผลว่าทำไมคนอื่นถึงไม่โดยเฉพาะอย่างยิ่งตัวชี้ที่ดิบ แต่นั่นไม่ใช่ขอบเขตของคำถามนี้ฉันเดา