ระบบประเภท: เล็กน้อยกับโครงสร้างชัดเจนและโดยนัย


24

ฉันสับสนเล็กน้อยเกี่ยวกับความแตกต่างระหว่างระบบประเภทเล็กน้อยและโครงสร้าง ใครช่วยกรุณาอธิบายว่าพวกเขาแตกต่างกันอย่างไร

จากสิ่งที่ฉันเข้าใจ:

  • ที่กำหนด: ความเข้ากันได้ประเภทขึ้นอยู่กับชื่อประเภท
  • โครงสร้าง: ประเภทที่เข้ากันได้จะขึ้นอยู่กับโครงสร้างประเภทเช่นใน C หากตัวแปร 2 ตัวเป็นประเภทโครงสร้างที่มีชื่อแตกต่างกัน แต่มีโครงสร้างเดียวกัน

ตอนนี้เกี่ยวกับชัดเจนและโดยนัย: ทำไมมันแตกต่างจากการพิมพ์แบบคงที่และแบบไดนามิก? ในการพิมพ์แบบคงที่ประเภทจะชัดเจนในขณะที่พิมพ์แบบไดนามิกประเภทจะมีความหมาย ฉันถูกไหม?

คำตอบ:


29

ในระบบที่พิมพ์แบบไดนามิกค่ามีชนิดที่รันไทม์ แต่ตัวแปรและฟังก์ชั่นไม่ได้ ในระบบที่พิมพ์แบบสแตติกตัวแปรและฟังก์ชั่นจะมีชนิดที่รู้จักและตรวจสอบ ณ เวลารวบรวม เช่นในหลามxสามารถเป็นอะไร ; ที่ runtime ถ้ามันเป็น1จำนวนและถ้ามันเป็น"foo"สตริง คุณจะรู้ว่าประเภทใดxที่ runtime และมันอาจแตกต่างกันในแต่ละครั้งที่คุณรันโปรแกรม ในภาษาเช่น Java, คุณจะเขียนint xถ้าxจะเป็นตัวเลขและคุณจะได้รู้ว่าที่รวบรวมเวลาที่มักจะต้องมีxint

"Explicit" และ "implicit" ทั้งคู่อ้างถึงระบบชนิดสแตติก ลักษณะการกำหนดของระบบสแตติกคือชนิดที่ทราบในเวลารวบรวม แต่ไม่จำเป็นต้องเขียนออกมา ใน Java ประเภทจะชัดเจน - คุณต้องเขียนมันออกมา ดังนั้นใน Java เมธอดอาจมีลักษณะดังนี้:

public int foo(String bar, Object baz) { ... }

ชนิดเป็นที่รู้จักกันในเวลารวบรวม (คงที่) และเขียนออกมา (ชัดเจน) อย่างไรก็ตามยังมีภาษาที่ไม่บังคับให้คุณเขียนรูปแบบ พวกเขาสามารถอนุมานประเภทของฟังก์ชั่นจากร่างกายของมันและวิธีการใช้งาน ตัวอย่างจะเป็น OCaml ซึ่งคุณสามารถเขียนสิ่งที่ชอบ:

let foo x = x + 1

ตั้งแต่คุณใช้+OCaml สามารถคิดxได้ว่าจะต้องเป็นintของตัวเองทั้งหมด ดังนั้นชนิดของfoo( foo : int -> int) จึงเป็นที่รู้จักกันในเวลารวบรวมเช่นเดียวกับตัวอย่างของ Java มันคงที่ทั้งหมด อย่างไรก็ตามเนื่องจากคอมไพเลอร์สามารถระบุประเภทที่ต้องเป็นของตัวเองคุณไม่จำเป็นต้องเขียนมันออกมาด้วยตัวเอง: โดยปริยาย

กล่าวโดยย่อ: ระบบประเภทไม่ชัดเจนหรือโดยนัยคือคุณสมบัติของระบบคงที่ มันเป็นคำถามที่แตกต่างอย่างสิ้นเชิงจากระบบประเภทที่เป็นแบบไดนามิกหรือแบบคงที่

บ่อยครั้งที่คุณมีระบบการพิมพ์ที่ชัดเจนและบางครั้งก็บอกเป็นนัย

ตัวอย่างเช่นฉันเชื่อว่า C # ช่วยให้คุณสามารถระบุประเภทโดยใช้varคำหลัก ดังนั้นแทนที่จะเขียนint x = 10คุณสามารถเขียนvar x = 10และเรียบเรียงตัวเลขออกมาว่าจะเป็นมีx intc ++ autoทำอะไรบางอย่างที่คล้ายกันด้วย ระบบเหล่านี้มักจะชัดเจน แต่มีการอนุมาน

บน flipside มีระบบที่มักจะบอกเป็นนัย แต่บางครั้งบังคับให้คุณเขียนลายเซ็นประเภท Haskell เป็นตัวอย่างที่ดี ส่วนใหญ่เวลา Haskell สามารถอนุมานประเภทสำหรับคุณ อย่างไรก็ตามบางครั้งคุณสามารถเขียนโค้ดที่ไม่ชัดเจนเช่นshow . readHaskell ซึ่งไม่สามารถระบุประเภทด้วยตนเองได้ ในกรณีนี้คุณจะถูกบังคับให้ชัดเจนระบุชนิดของทั้งสองหรือshow readนอกจากนี้คุณสมบัติขั้นสูงบางอย่างของระบบประเภท (เช่น polymorphism อันดับ -n) ทำให้การอนุมานไม่สามารถตัดสินใจได้ - นั่นคือมันไม่รับประกันว่าจะหยุด ซึ่งหมายความว่ารหัสที่ใช้คุณสมบัตินี้มักจะต้องการลายเซ็นประเภทที่ชัดเจน


2
จริงๆแล้วมีบางภาษาที่คุณสามารถเรียกการพิมพ์แบบไดนามิกที่ชัดเจนได้ โดยทั่วไปภาษาเหล่านั้นจะช่วยให้คุณใส่คำอธิบายประกอบด้วยนิพจน์แล้วประเภทเหล่านั้นจะถูกตรวจสอบที่รันไทม์กับประเภทรันไทม์ของการแสดงออก
— Jörg W Mittag

แค่ความแม่นยำ: ระบบพิมพ์ไม่ได้บอกเป็นนัยหรือชัดเจน นี่เป็นเพียงการอนุมานประเภทซึ่งเป็นวิธีการสร้างคำที่ถูกต้องในระบบพิมพ์จากไวยากรณ์ที่แตกต่างกัน (บางครั้งไม่ได้ระบุ)
— Eduardo Pareja Tobes

คำตอบที่ดี แต่สิ่งนี้ไม่ได้ระบุถึงการพิมพ์ตามโครงสร้างเล็กน้อย การแก้ไขจะดีมาก
— lunchmeat317

7
  • static vs dynamic อธิบายเมื่อมีการตรวจสอบประเภท (มากหรือน้อยในเวลารวบรวมหรือเวลาดำเนินการ)

  • Nominal vs structure อธิบายเมื่อทั้งสองประเภทได้รับการพิจารณาเหมือนกัน

(และมีรูปแบบต่าง ๆ ที่รู้จักกันดีที่สุดคือความแตกต่างของการพิมพ์เชิงโครงสร้างซึ่งพิจารณาเฉพาะสิ่งที่ใช้แทนประเภททั้งหมดที่รู้จักกันในชื่อการพิมพ์เป็ด)

การรวมสี่แบบ (คงที่แบบคงที่โครงสร้างคงที่แบบไดนามิกเล็กน้อยแบบไดนามิกโครงสร้าง) เป็นไปได้และภาษาค่อนข้างบ่อยไม่ได้อยู่ในชั้นเดียว แต่มีแง่มุมที่อยู่ในคนอื่น ๆ

ตัวอย่างเช่นระบบชนิดของ C ++ นั้นเป็นแบบสแตติกส่วนใหญ่จะเป็นชื่อแบบโครงสร้าง แต่เมื่อคุณพิจารณาแม่แบบ (และคุณสามารถพิจารณาปัญหาส่วนหนึ่งของแนวคิดใน C ++ ซึ่งเป็นข้อขัดแย้งระหว่างสิ่งที่ต้องการจากการพิมพ์เป็ดไปจนถึงแบบเต็มรูปแบบ ผู้ที่ต้องการไปพิมพ์แบบปกติ) และการใช้คลาสและการสืบทอดทำให้สามารถใช้การพิมพ์แบบไดนามิกและระบุในบางกรณี

ภาษาที่ระบบการพิมพ์แบบไดนามิกมักจะใช้การพิมพ์โครงสร้าง แต่ CLOS เป็นลักษณะเล็กน้อย


1

โครงสร้าง: ประเภทที่เข้ากันได้จะขึ้นอยู่กับโครงสร้างประเภทเช่นใน C หากตัวแปร 2 ตัวเป็นประเภทโครงสร้างที่มีชื่อแตกต่างกัน แต่มีโครงสร้างเดียวกัน

นี่ไม่ใช่กรณีปกติ การพิมพ์แบบโครงสร้างหมายถึงว่าBมันเป็นประเภทย่อยของAถ้ามันสามารถตอบสนองAอินเทอร์เฟซของ มักจะหมายถึงการมีสมาชิกที่มีชื่อเดียวกัน ไม่เพียง แต่โครงสร้างเดียวกันในหน่วยความจำ

สิ่งนี้แตกต่างจากการพิมพ์แบบบอกกล่าวที่ต้องระบุประเภทแบบพิเศษในการประกาศ


1

คำอธิบายที่ดีที่สุดที่ฉันได้เห็นถึงความแตกต่างระหว่าง (แบบไดนามิก) กับระบบประเภทไดนามิกและแบบคงที่อยู่ในบล็อกโพสต์นี้โดย Bob Harper:

ประเด็นหลักสามารถสรุปได้ดังนี้:

  • ภาษาไดนามิกเป็นภาษาสแตติกที่มีเพียงชนิดเดียว

1
ลิงค์สามารถไปได้ไม่ดี; คุณควรอ้างอิงส่วนที่เกี่ยวข้องมากที่สุดของบทความเพื่อให้พวกเขาได้รับการเก็บรักษาไว้เพื่อลูกหลานแม้ว่าบล็อกนั้นจะหายไป
— Doval

2
แน่ใจ ผมคิดว่าในกรณีนี้ผมประโยคเพิ่มเป็นพอ :)
— Eduardo Pareja Tobes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.