StaDyn (ภาษาโปรแกรม)
| สตาไดน์ | |
|---|---|
| กระบวนทัศน์ | เชิงวัตถุ |
| ออกแบบ โดย | ฟรานซิสโก ออร์ทิน[ 1 ] |
| นักพัฒนา | กลุ่มวิจัยการสะท้อนเชิงคำนวณ[ 2 ]ของมหาวิทยาลัยโอเวียโด |
| ปรากฏครั้งแรก | 2007 |
| เวอร์ชันเสถียร | 2.2.1 / 11 พฤษภาคม 2022 |
| วินัยในการพิมพ์ | การพิมพ์แบบผสมผสานระหว่างแบบคงที่และแบบไดนามิก การพิมพ์แบบค่อยเป็นค่อยไป การพิมพ์แบบเข้มงวด การพิมพ์แบบอนุมาน |
| ภาษาการใช้งาน | ซี# |
| แพลตฟอร์ม | โครงสร้างพื้นฐานภาษาทั่วไป ( .NET Framework ) |
| ใบอนุญาต | ใบอนุญาต MIT [ 3 ] |
| เว็บไซต์ | reflection |
| การนำไปใช้งานหลักๆ | |
| ซี# | |
| ได้รับอิทธิพลจาก | |
| C# , OCaml , StrongTalk , Boo | |
StaDynเป็น ภาษาโปรแกรมเชิง วัตถุอเนกประสงค์สำหรับแพลตฟอร์ม .NETที่รองรับทั้งการกำหนดประเภทข้อมูลแบบคงที่และแบบไดนามิกในภาษาโปรแกรมเดียวกัน
คอมไพเลอร์ StaDyn รวบรวมข้อมูลประเภทสำหรับโค้ดแบบไดนามิก ข้อมูลประเภทนั้นใช้เพื่อตรวจจับข้อผิดพลาดประเภทในระหว่างการคอมไพล์และเพื่อทำการเพิ่มประสิทธิภาพอย่างมีนัยสำคัญ ด้วยเหตุนี้จึงมีการสร้างประเภทใหม่ (การอนุมาน) ประเภทที่ไวต่อการไหล ประเภทการรวมและการตัดกัน การกำหนดประเภทตามข้อจำกัด การวิเคราะห์นามแฝง และการกำหนดวิธีการเฉพาะ ต้นแบบแรกปรากฏขึ้นในปี 2550 ในฐานะการดัดแปลง C# 3.0 การอนุมานประเภทได้รับการสนับสนุนโดยการรวมvarเป็นประเภทใหม่ ซึ่งแตกต่างจาก C# ที่เสนอvarให้กำหนดตัวแปรโลคอลที่เริ่มต้นเท่านั้น ประเภทที่ไวต่อการไหลของvarการอ้างอิงจะถูกอนุมานโดยคอมไพเลอร์ ทำให้เกิดการกำหนดประเภทแบบ duck ที่ปลอดภัย[ 4 ]เมื่อโปรแกรมเมอร์ต้องการแนวทางที่ผ่อนปรนมากขึ้นdynamicสามารถใช้ประเภทแทนได้varแม้ว่าจะยังคงดำเนินการอนุมานประเภทอยู่ แต่dynamicการอ้างอิงจะทำงานใกล้เคียงกับในภาษาไดนามิกมากขึ้น
StaDyn ได้รับการออกแบบโดย Francisco Ortin [ 1 ]จากมหาวิทยาลัย Oviedoภาษาดังกล่าวได้รับการนำไปใช้โดยสมาชิกต่างๆ ของกลุ่มวิจัย Computational Reflection [ 2 ]รวมถึง Miguel Garcia, Jose Baltasar García Perez-Schofield และ Jose Quiroga นอกเหนือจาก Francisco Ortin
ชื่อ StaDyn มาจากการรวมคำว่า static และ dynamic เข้าด้วยกัน ซึ่งแสดงให้เห็นถึงเป้าหมายในการมอบข้อดีของทั้งการพิมพ์แบบคงที่และแบบไดนามิก
ตัวอย่างโค้ด
ตัวแปรที่มีประเภทต่างกัน
เช่นเดียวกับภาษาโปรแกรมแบบไดนามิก ตัวแปรอาจเก็บค่าประเภทต่างๆ กันในขอบเขตเดียวกันได้:
using System ; class Program { public static void Main ( ) { Console.Write ( "Number: " ) ; var age = Console.In.ReadLine ( ) ; Console.WriteLine ( " Digits : " + age.Length ) ; } }อายุ= แปลงเป็นจำนวนเต็ม32 ( อายุ); อายุเพิ่มขึ้น 1 เท่า;Console.WriteLine ( "สุขสันต์วันเกิด คุณอายุ " + age + " ปีแล้ว" ); int length = age.Length ; // * ข้อผิดพลาดของคอมไพเลอร์} }ตัวแปรageถูกตีความว่าเป็นสตริงก่อน ดังนั้นจึงปลอดภัยที่จะเข้าถึงLengthคุณสมบัติของมัน จากนั้นมันเก็บค่าจำนวนเต็ม ดังนั้นจึงage++เป็นนิพจน์ที่ถูกต้อง คอมไพเลอร์ตรวจพบข้อผิดพลาดในบรรทัดสุดท้าย เนื่องจากLengthไม่ได้ระบุค่าอีกต่อไปageแล้ว
โค้ดที่สร้างขึ้นไม่ได้ใช้Objectตัวแปรเดียวในการแสดงอายุ แต่ใช้ตัวแปรสองตัวที่แตกต่างกันซึ่งมีประเภทเป็นสตริงและจำนวนเต็ม ซึ่งทำได้โดยการปรับเปลี่ยนอัลกอริธึมในการคำนวณ แบบ ฟอร์มSSA [ 5 ]ทำให้โค้ดที่สร้างขึ้นมีประสิทธิภาพมากขึ้น เนื่องจากไม่จำเป็นต้องแปลงประเภทในขณะรันไทม์
ประเภทที่ไวต่อการไหล
varและdynamicตัวแปรสามารถเก็บประเภทข้อมูลที่ไวต่อการไหลได้:
using System ; class Program { public static void Main ( String [] args ) { var exception ; if ( args.Length > 0 ) exception = new ApplicationException ( " An application exception." ) ; else exception = new SystemException ( " A system exception ." ); Console.WriteLine ( exception.Message ) ; } }Messageการดึงค่า คุณสมบัติจาก ทั้งสองอย่าง นั้นปลอดภัยexceptionเพราะทั้งสอง อย่างต่าง ApplicationExceptionก็SystemExceptionมีคุณสมบัตินั้น มิฉะนั้นจะแสดงข้อผิดพลาดของคอมไพเลอร์ ด้วยวิธีนี้ StaDyn จึงมีระบบการสร้างประเภทข้อมูลแบบคงที่ที่ปลอดภัยต่อประเภทข้อมูล
ในโปรแกรมต่อไปนี้:
using System ; class Program { public static void Main ( String [] args ) { var exception ; switch ( args.Length ) { case 0 : exception = new ApplicationException ( "An application exception." ); break ; case 1 : exception = new SystemException ( "A system exception." ); break ; default : exception = "This is not an exception." ; break ; } Console.WriteLine ( exception.Message ) ; // * ข้อผิดพลาดของคอม ไพเลอร์กับ var แต่ไม่ใช่กับ dynamic Console.WriteLine ( exception.Unknown ) ; // * ข้อผิดพลาดของคอมไพเลอร์} }คุณสมบัติMessageไม่ได้จัดเตรียมโดยStringดังนั้นข้อผิดพลาดของคอมไพเลอร์จึงแสดงขึ้นสำหรับexception.Messageอย่างไรก็ตาม หากเราประกาศexceptionเป็นdynamicโปรแกรมก่อนหน้านี้จะได้รับการยอมรับจากคอมไพเลอร์dynamicมีความยืดหยุ่นมากกว่าvarตามแบบฉบับของภาษาไดนามิก อย่างไรก็ตาม การตรวจสอบประเภทแบบคงที่ยังคงดำเนินการอยู่ สิ่งนี้แสดงให้เห็นในบรรทัดสุดท้ายของโค้ด ซึ่งคอมไพเลอร์แสดงข้อผิดพลาดสำหรับexception.Unknownแม้ว่าexceptionจะถูกประกาศเป็น ก็ตามdynamicนี่เป็นเพราะประเภทที่เป็นไปได้ทั้งสามประเภท ( ApplicationException, SystemExceptionและString) ไม่รองรับUnknownข้อความ[ 6 ]
แม้ว่า ประเภท dynamicและvarสามารถใช้อย่างชัดเจนเพื่อให้ได้การตรวจสอบประเภทที่ปลอดภัยหรือผ่อนปรนมากขึ้น แต่ไดนามิกของvarการอ้างอิงเดี่ยวก็สามารถแก้ไขได้ด้วยตัวเลือกบรรทัดคำสั่ง ไฟล์การกำหนดค่า XML และปลั๊กอินสำหรับ Visual Studio [ 7 ]
การอนุมานประเภทของฟิลด์
varและdynamicประเภทต่างๆ สามารถใช้เป็นฟิลด์ของอ็อบเจ็กต์ได้:
คลาสWrapper { private var attribute ;public Wrapper ( var attribute ) { this . attribute = attribute ; }public var get () { return attribute ; }public void set ( var attribute ) { this.attribute = attribute ; } }คลาสTest { public static void Main () { string aString ; int aInt ; Wrapper wrapper = new Wrapper ( "Hello" ); aString = wrapper . get (); aInt = wrapper . get (); // * ข้อผิดพลาดของคอมไพเลอร์wrapper.set ( 3 ); aString = wrapper.get ( ); // * ข้อผิดพลาดของคอมไพเลอร์aInt = wrapper.get ( ) ; } }คลาส นี้Wrapperสามารถห่อหุ้มประเภทใดก็ได้ ทุกครั้งที่เราเรียกsetเมธอด ประเภทของattributeจะถูกอนุมานเป็นประเภทของอาร์กิวเมนต์ แต่ละอ็อบเจ็กต์มีประเภทของที่อาจแตกต่างกันattributeดังนั้นประเภทของมันจึงถูกจัดเก็บไว้สำหรับแต่ละอินสแตนซ์แทนที่จะเป็นทั้งคลาส ด้วยวิธีนี้ บรรทัดสองบรรทัดที่ระบุในโค้ดข้างต้นจะรายงานข้อผิดพลาดในการคอมไพล์ อัลกอริทึมการวิเคราะห์นามแฝงตามประเภทถูกนำมาใช้เพื่อรองรับพฤติกรรมนี้[ 8 ]
ประเภทตามข้อจำกัด
เรามาวิเคราะห์วิธีการต่อไปนี้กัน:
สาธารณะvar บนคงที่( พารามิเตอร์var ) { พารามิเตอร์ส่งคืนถึงด้านบน(); }parameterคอมไพเลอร์จะอนุมานประเภทของฟังก์ชัน และค่าส่งคืนของฟังก์ชัน เพื่อให้ได้ผลลัพธ์ดังกล่าว จะมีการเพิ่มข้อจำกัดให้กับประเภทของ upperเมธอด: อาร์กิวเมนต์จะต้องเป็นToUpperเมธอดที่ไม่มีพารามิเตอร์ ในแต่ละครั้งที่เรียกใช้ จะมีการตรวจสอบข้อจำกัดนี้ นอกจากนี้ ประเภทการส่งคืนของฟังก์ชันupperจะถูกอนุมานเป็นประเภทการส่งคืนของToUpperเมธอดที่เกี่ยวข้องซึ่งถูกใช้งานโดยอาร์กิวเมนต์[ 9 ]
โปรแกรมเมอร์สามารถใช้ `or` varหรือ `or` dynamicเพื่อประกาศparameterตัวแปร `type` ซึ่งจะเปลี่ยนวิธีการตรวจสอบประเภทเมื่อเรียกใช้เมธอด สมมติว่าอาร์กิวเมนต์ที่ส่งไปยัง `type` upperมีประเภทที่ไวต่อการไหลของโปรแกรม (เช่น `var` ApplicationExceptionหรือSystemException` Stringexceptionvar` ในโค้ดด้านบน) หากใช้var` or` ประเภทที่เป็นไปได้ ทั้งหมดของอาร์กิวเมนต์จะต้องให้ค่าToUpper`true` ในขณะที่หากใช้ ` dynamicor` อย่างน้อยหนึ่งประเภทจะต้องให้ค่าToUpper`true`
ประสิทธิภาพการทำงานขณะรันไทม์
ข้อมูลประเภทที่รวบรวมโดย StaDyn ถูกนำมาใช้เพื่อดำเนินการเพิ่มประสิทธิภาพที่สำคัญในโค้ดที่สร้างขึ้น: [ 10 ]จำนวนการตรวจสอบประเภทและการแปลงประเภทลดลง หลีกเลี่ยงการสะท้อน แคชประเภทที่ใช้บ่อย และปรับแต่งเมธอดที่มีข้อจำกัด จุดประสงค์ของการเพิ่มประสิทธิภาพทั้งหมดคือการลดจำนวนการตรวจสอบประเภทที่ดำเนินการในขณะรันไทม์ ซึ่งเป็นโทษหลักของประสิทธิภาพของภาษาไดนามิกส่วนใหญ่ การตรวจสอบประเภทเหล่านั้นจำนวนมากดำเนินการก่อนหน้านี้โดยคอมไพเลอร์ StaDyn การประเมินประสิทธิภาพการทำงานของ StaDyn อย่างละเอียดมีรายละเอียดอยู่ใน[ 4 ]
ดูเพิ่มเติม
ลิงก์ภายนอก
- เว็บไซต์อย่างเป็นทางการ
- คลังเก็บข้อมูล GitHub
- กลุ่มวิจัยการสะท้อนเชิงคำนวณ