โดยปกติหากไลบรารีมีประเภททั่วไป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 และทดสอบพวกเขาทั้งหมด (โปรดบอกฉันว่ารหัสนี้ไม่สมเหตุสมผล) ดูเหมือนว่าการอ้างอิงเป็นประเภทพื้นฐานดั้งเดิมเท่านั้น น่าสนใจ ฉันสนใจที่จะรู้เหตุผลว่าทำไมคนอื่นถึงไม่โดยเฉพาะอย่างยิ่งตัวชี้ที่ดิบ แต่นั่นไม่ใช่ขอบเขตของคำถามนี้ฉันเดา