ระบบประเภทนั้นจะพิสูจน์ได้อย่างอัตโนมัติในบางแง่มุมของความถูกต้อง ตัวอย่างเช่นระบบชนิดของสนิมสามารถพิสูจน์ได้ว่าการอ้างอิงไม่ได้อยู่เหนือกว่าวัตถุที่อ้างอิงหรือว่าวัตถุที่อ้างอิงไม่ได้ถูกแก้ไขโดยเธรดอื่น
แต่ระบบประเภทค่อนข้าง จำกัด :
พวกเขาพบปัญหาในการตัดสินใจได้อย่างรวดเร็ว โดยเฉพาะอย่างยิ่งระบบพิมพ์ควรจะสามารถถอดรหัสได้ แต่ระบบการพิมพ์ที่ใช้งานได้จริงจำนวนมากโดยไม่ได้ตั้งใจทำให้ทัวริงสมบูรณ์ (รวมถึง C ++ เนื่องจากเทมเพลตและสนิมเนื่องจากลักษณะ) นอกจากนี้คุณสมบัติบางอย่างของโปรแกรมที่พวกเขากำลังตรวจสอบอาจไม่สามารถตัดสินใจได้ในกรณีทั่วไปส่วนใหญ่มีชื่อเสียงว่าโปรแกรมบางโปรแกรมหยุดทำงาน (หรือเปลี่ยนทิศทาง)
นอกจากนี้ระบบการพิมพ์ควรทำงานได้อย่างรวดเร็วในเวลาเชิงเส้น ไม่ควรแสดงหลักฐานทั้งหมดที่เป็นไปได้ในระบบพิมพ์ เช่นการวิเคราะห์โปรแกรมทั้งหมดมักจะหลีกเลี่ยงและการพิสูจน์จะถูกกำหนดขอบเขตให้กับโมดูลหรือฟังก์ชั่นเดียว
เนื่องจากข้อ จำกัด เหล่านี้ระบบพิมพ์มักจะตรวจสอบคุณสมบัติที่ค่อนข้างอ่อนแอซึ่งง่ายต่อการพิสูจน์เช่นว่าฟังก์ชันถูกเรียกใช้ด้วยค่าประเภทที่ถูกต้อง แต่ถึงกระนั้นก็ตามนั่นก็มีข้อ จำกัด อย่างมากในเรื่องของการแสดงออกดังนั้นจึงเป็นเรื่องปกติที่จะมีวิธีแก้ปัญหา (เช่นinterface{}
ใน Go, dynamic
C #, Object
Java, void*
C) หรือแม้แต่การใช้ภาษาที่หลีกเลี่ยงการพิมพ์แบบคงที่
คุณสมบัติที่แข็งแกร่งกว่าที่เราตรวจสอบความสามารถในการแสดงออกของภาษาจะน้อยลง หากคุณเขียน Rust คุณจะรู้ว่าช่วงเวลา“ การต่อสู้กับคอมไพเลอร์” เหล่านี้โดยที่คอมไพเลอร์ปฏิเสธรหัสที่ดูเหมือนจะถูกต้องเพราะมันไม่สามารถพิสูจน์ความถูกต้องได้ ในบางกรณีเป็นไปไม่ได้ที่จะแสดงโปรแกรมบางอย่างใน Rust แม้ว่าเราเชื่อว่าเราสามารถพิสูจน์ความถูกต้องได้ unsafe
กลไกใน Rust หรือ C # ช่วยให้คุณสามารถที่จะหลบหนีขอบเขตของระบบการพิมพ์ที่ ในบางกรณีการชะลอการตรวจสอบรันไทม์อาจเป็นอีกทางเลือกหนึ่ง - แต่นี่หมายความว่าเราไม่สามารถปฏิเสธโปรแกรมที่ไม่ถูกต้องได้ นี่เป็นเรื่องของคำนิยาม โปรแกรม Rust ที่ตื่นตระหนกมีความปลอดภัยเท่าที่เกี่ยวข้องกับประเภทของระบบ แต่ไม่จำเป็นต้องมาจากมุมมองของโปรแกรมเมอร์หรือผู้ใช้
ภาษาได้รับการออกแบบพร้อมกับระบบชนิดของพวกเขา เป็นเรื่องยากที่ระบบชนิดใหม่จะถูกกำหนดในภาษาที่มีอยู่ (แต่ดูเช่น MyPy, Flow หรือ TypeScript) ภาษาจะพยายามทำให้ง่ายต่อการเขียนรหัสที่สอดคล้องกับระบบประเภทเช่นโดยเสนอคำอธิบายประกอบประเภทหรือโดยการแนะนำง่ายต่อการพิสูจน์โครงสร้างการไหลของการควบคุม ภาษาที่แตกต่างกันอาจจบลงด้วยการแก้ปัญหาที่แตกต่างกัน เช่น Java มีแนวคิดของfinal
ตัวแปรที่ได้รับมอบหมายเพียงครั้งเดียวคล้ายกับmut
ตัวแปรที่ไม่ใช่ของ Rust :
final int x;
if (...) { ... }
else { ... }
doSomethingWith(x);
Java มีกฎระบบชนิดเพื่อตรวจสอบว่าเส้นทางทั้งหมดกำหนดตัวแปรหรือยกเลิกฟังก์ชั่นก่อนที่จะสามารถเข้าถึงตัวแปร ในทางตรงกันข้าม Rust ทำให้การพิสูจน์นี้ง่ายขึ้นโดยไม่มีตัวแปรที่ประกาศ แต่ไม่ได้ออกแบบ แต่ให้คุณคืนค่าจากคำสั่งโฟลว์ควบคุม:
let x = if ... { ... } else { ... };
do_something_with(x)
ดูเหมือนว่าจะเป็นจุดเล็ก ๆ น้อย ๆ เมื่อทำการกำหนด แต่การกำหนดขอบเขตที่ชัดเจนเป็นสิ่งสำคัญอย่างยิ่งสำหรับการพิสูจน์ที่เกี่ยวข้องกับชีวิต
ถ้าเราจะใช้ระบบการพิมพ์สนิมสไตล์ Java เราจะมีปัญหาใหญ่กว่าที่: วัตถุ Java ไม่ได้มีคำอธิบายประกอบกับอายุการใช้งานดังนั้นเราจะต้องรักษาพวกเขาเป็นหรือ&'static SomeClass
Arc<dyn SomeClass>
นั่นจะทำให้ข้อพิสูจน์ที่อ่อนแอลง Java ยังไม่มีแนวคิดระดับประเภทของการเปลี่ยนไม่ได้ดังนั้นเราจึงไม่สามารถแยกความแตกต่างระหว่าง&
และ&mut
ประเภท เราจะต้องปฏิบัติต่อวัตถุใด ๆ ในฐานะที่เป็น Cell หรือ Mutex แม้ว่าสิ่งนี้อาจถือว่าการค้ำประกันที่แข็งแกร่งกว่า Java ที่นำเสนอจริง ในที่สุด Rust ไม่มีแนวคิดเกี่ยวกับการสืบทอดการใช้งานสไตล์ Java
TL; DR:ระบบชนิดเป็นตัวพิสูจน์ทฤษฎีบท แต่จะถูก จำกัด ด้วยปัญหาความสามารถในการตัดสินใจและความกังวลด้านประสิทธิภาพ คุณไม่สามารถใช้ระบบประเภทเดียวและนำไปใช้กับภาษาอื่นได้เนื่องจากไวยากรณ์ภาษาของเป้าหมายอาจไม่ให้ข้อมูลที่จำเป็นและเนื่องจากความหมายอาจเข้ากันไม่ได้