คงที่ / ไดนามิก vs แข็งแกร่ง / อ่อนแอ


319

ฉันเห็นคำเหล่านี้รวมตัวกันรอบ ๆ สถานที่ในการเขียนโปรแกรมและฉันมีความคิดที่คลุมเครือของสิ่งที่พวกเขาหมายถึง การค้นหาแสดงให้ฉันเห็นว่ามีการขอให้สิ่งต่าง ๆ ดังกล่าวหมดไปในความเป็นจริง เท่าที่ฉันทราบการพิมพ์แบบสแตติก / ไดนามิกในภาษานั้นแตกต่างอย่างมากจากการพิมพ์แบบ Strong / Weak แต่สิ่งที่แตกต่างนั้นทำให้ฉันหลง แหล่งที่มาที่แตกต่างกันดูเหมือนจะใช้ความหมายที่แตกต่างกันหรือแม้กระทั่งใช้คำที่สลับกันได้ ฉันไม่สามารถหาที่ไหนสักแห่งที่พูดถึงทั้งคู่และสะกดความแตกต่าง จะมีอะไรดีถ้ามีคนโปรดสะกดคำนี้ออกมาให้ชัดเจนสำหรับฉันและคนอื่น ๆ ในโลก



คำตอบ:


423
  • แบบคงที่ / การพิมพ์แบบไดนามิกเป็นเรื่องเกี่ยวกับเมื่อได้รับข้อมูลประเภท (ทั้งในเวลารวบรวมหรือที่รันไทม์)

  • Strong / Weak Typingเป็นเรื่องเกี่ยวกับความแตกต่างของชนิดอย่างเข้มงวด (เช่นว่าภาษาพยายามทำการแปลงโดยนัยจากสตริงเป็นตัวเลข)

ดูหน้าwikiสำหรับข้อมูลรายละเอียดเพิ่มเติม


7
Wikipedia มีคำตอบทั้งหมด ทำไมฉันถึงไม่ได้เจอสิ่งนี้เลยฉันไม่รู้
Dan Revell

31
เป็นเรื่องน่าละอายที่หลายคนไม่ทราบว่าสแตติก / ไดนามิกเป็นอย่างอื่นที่แข็งแกร่ง / อ่อนแอ ... จริง ๆ แล้วมันจะบันทึกอคติและการสนทนาบางอย่าง
Dykam

10
มี "องศาความอ่อนแอ" ที่แตกต่างกันไป ภาษาที่พิมพ์อย่างรุนแรงอาจพยายามแปลงจากสตริงเป็นตัวเลข ในทางกลับกัน HyperTalk (ภาษาที่ฉันใช้เมื่อหลายสิบปีก่อน) ถูกพิมพ์อย่างอ่อนที่"12" + "34"จะเท่ากัน"46"แต่"12" + "34Q"จะเท่ากับ"1234Q"[โชคดีเราสามารถเขียนได้"12" & "34"หากต้องการเรียงต่อกัน] อยากรู้อยากเห็นตัวแปรถือตัวเลขที่เก็บไว้เป็นความแม่นยำสองเท่าลอยและคณิตศาสตร์ในตัวแปรดังกล่าวใช้ค่าจุดลอยตัวโดยไม่ต้องสตริง munging แต่ไม่มีวิธีที่จะถามว่าตัวแปรเป็นสตริงหรือตัวเลข
supercat

9
@kittylyst ฉันไม่สามารถดูได้ว่าคำตอบนี้แสดงให้เห็นว่าคำว่า strong เป็นคำพ้องสำหรับ static
Pete

4
++ สำหรับคำจำกัดความบรรทัดเดียว (ประมาณ)
JamesFaix

211

คุณได้ค้นพบจุดอ่อนในคำศัพท์ที่มือสมัครเล่นใช้เพื่อพูดคุยเกี่ยวกับภาษาการเขียนโปรแกรม อย่าใช้คำว่า "แข็งแรง" และ "อ่อนแอ" ในการพิมพ์เพราะพวกเขาไม่มีความเห็นในระดับสากลเกี่ยวกับความหมายทางเทคนิค ในทางตรงกันข้ามการพิมพ์แบบสแตติกหมายถึงมีการตรวจสอบโปรแกรมก่อนที่จะดำเนินการและโปรแกรมอาจถูกปฏิเสธก่อนที่จะเริ่มต้น การพิมพ์แบบไดนามิกหมายความว่าประเภทของค่าจะถูกตรวจสอบในระหว่างการดำเนินการและการดำเนินการพิมพ์ไม่ดีอาจทำให้โปรแกรมหยุดหรือส่งสัญญาณข้อผิดพลาดในเวลาทำงานสัญญาณข้อผิดพลาดในเวลาทำงานเหตุผลหลักสำหรับการพิมพ์แบบคงที่คือการออกกฎโปรแกรมที่อาจมี "ข้อผิดพลาดประเภทแบบไดนามิก"

โดยทั่วไปการพิมพ์ที่แข็งแกร่งหมายความว่าไม่มีช่องโหว่ในระบบพิมพ์ในขณะที่การพิมพ์ที่อ่อนแอหมายถึงระบบพิมพ์สามารถล้มล้างได้ (ทำให้การรับรองใด ๆ เป็นโมฆะ) คำศัพท์มักใช้อย่างไม่ถูกต้องเพื่อหมายถึงการพิมพ์แบบคงที่และแบบไดนามิก หากต้องการดูความแตกต่างให้นึกถึง C: ภาษาจะถูกตรวจสอบประเภทในเวลารวบรวม (การพิมพ์คงที่) แต่มีช่องโหว่มากมาย คุณสามารถแปลงค่าประเภทใดก็ได้เป็นขนาดอื่น --- โดยเฉพาะอย่างยิ่งคุณสามารถส่งประเภทตัวชี้ได้อย่างอิสระ ปาสคาลเป็นภาษาที่ตั้งใจจะพิมพ์อย่างยิ่ง แต่มีชื่อเสียงมีช่องโหว่ที่ไม่คาดฝัน: บันทึกตัวแปรที่ไม่มีแท็ก

การใช้ภาษาที่มีการพิมพ์อย่างมากมักจะมีช่องโหว่เมื่อเวลาผ่านไปซึ่งโดยปกติจะทำให้ส่วนของระบบรันไทม์สามารถใช้งานในภาษาระดับสูงได้ ตัวอย่างเช่น Objective Caml มีฟังก์ชั่นที่เรียกว่าObj.magicซึ่งมีเอฟเฟกต์แบบรันไทม์เพียงแค่คืนค่าอาร์กิวเมนต์ แต่ในเวลาคอมไพล์มันจะแปลงค่าของประเภทใด ๆ ให้เป็นหนึ่งในประเภทอื่น ๆ ตัวอย่างที่ฉันชอบคือ Modula-3 ซึ่งนักออกแบบเรียกว่าโครงสร้างการหล่อแบบของพวกเขาLOOPHOLEซึ่งเป็นนักออกแบบที่เรียกว่าสร้างประเภทหล่อของพวกเขา

ต้องบอกว่าคุณไม่สามารถนับคนสองคนที่ใช้คำว่า "แข็งแรง" และ "อ่อนแอ" ในลักษณะเดียวกันได้ ดังนั้นหลีกเลี่ยงพวกเขา


31
(+1) สำหรับคำแนะนำของคุณเพื่อหลีกเลี่ยงคำว่า "แข็ง" และ "อ่อนแอ"
Nico

1
เห็นด้วยเป็นเพียงการอ่านหนังสือของ Jon Skeet และนี่เป็นคำตอบเดียวกับที่มี
Bennett Yeates

เท่าที่ฉันทราบ Java มีช่องโหว่เหล่านี้เช่นกัน แต่ก็ยังถือว่าเป็นภาษาที่พิมพ์อย่างรุนแรงดังนั้นฉันเดาว่านี่จะให้น้ำหนักมากกว่าคำแนะนำของคุณในการหลีกเลี่ยงคำว่า "แข็งแรง" และ "อ่อนแอ"
doubleOrt

74

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

ตัวอย่างเช่นใน Java:

String str = "Hello";  //statically typed as string
str = 5;               //would throw an error since java is statically typed

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

ตัวอย่างเช่นใน Python:

str = "Hello" # it is a string
str = 5       # now it is an integer; perfectly OK

ในทางกลับกันการพิมพ์ที่รัดกุม / อ่อนแอในภาษานั้นเกี่ยวข้องกับการแปลงประเภทโดยนัย (ส่วนหนึ่งมาจากคำตอบของ @ Dario):

ตัวอย่างเช่นใน Python:

str = 5 + "hello" 
# would throw an error since it does not want to cast one type to the other implicitly. 

ในขณะที่ใน PHP:

$str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0 
// PHP is weakly typed, thus is a very forgiving language.

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


2
คำตอบที่ดีและความรุ่งโรจน์สำหรับการใช้ตัวอย่างที่เป็นรูปธรรม
Julian A.

3
นี่คือเหตุผลที่ PHP จำเป็นต้องใช้ด้วยความระมัดระวัง
Ali Gajani

1
ตัวอย่างภาษามีประโยชน์จริง ๆ ชื่นชมมาก
J Mullen

ในแง่นี้ Java จะถูกพิมพ์อย่างอ่อนช้อยเล็กน้อยเพราะคุณสามารถต่อเชื่อมสตริงที่ไม่ใช่กับสตริงได้และเพราะ auto-unboxing / boxing?
สตีเฟ่นพอล

1
@StephenPaul คุณถูกต้องคำตอบของฉันอาจจะเข้าใจวิธีการที่และมันก็ไม่ใช่กรณี ฉันใช้การเรียงต่อกันเพื่อประโยชน์ของความเรียบง่าย แต่ในความเป็นจริงความแข็งแรง / จุดอ่อนนั้นเกี่ยวกับการแปลงชนิดของตัวแปรโดยปริยาย
mehmet

20

การพิมพ์ที่อ่อนแอหมายถึงประเภทของวัตถุสามารถเปลี่ยนแปลงได้ขึ้นอยู่กับบริบท ตัวอย่างเช่นในภาษาที่พิมพ์อย่างอ่อนสตริง "123" อาจถือว่าเป็นหมายเลข 123 หากคุณเพิ่มหมายเลขอื่นลงไป ตัวอย่างของภาษาที่มีการพิมพ์ที่ไม่ดี ได้แก่ bash, awk และ PHP

ภาษาที่พิมพ์อย่างอ่อนอีกประเภทหนึ่งคือ C ซึ่งข้อมูลที่อยู่หน่วยความจำสามารถถือว่าเป็นประเภทที่แตกต่างกันโดยการส่ง

ในภาษาที่พิมพ์อย่างรุนแรงชนิดของวัตถุจะไม่เปลี่ยนแปลง - int มักเป็น int และพยายามใช้งานเป็นสตริงจะทำให้เกิดข้อผิดพลาด พิมพ์ทั้ง Java และ Python อย่างยิ่ง

ความแตกต่างระหว่างการพิมพ์แบบไดนามิกและแบบคงที่คือเมื่อมีการบังคับใช้กฎประเภท ในภาษาที่พิมพ์แบบคงที่ประเภทของตัวแปรและพารามิเตอร์ทั้งหมดจะต้องประกาศในแหล่งที่มาและมีการบังคับใช้ในเวลารวบรวม ในภาษาที่พิมพ์แบบไดนามิกประเภทจะถูกตรวจสอบเฉพาะเมื่อพวกเขาจะใช้เวลารันไทม์ ดังนั้น Java ถูกพิมพ์แบบสแตติกและ Python ถูกพิมพ์แบบไดนามิก

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

ภาษาที่พิมพ์อย่างรุนแรงที่สุดในทำนองเดียวกันจะยังคงแปลงโดยอัตโนมัติระหว่างจำนวนเต็มและจำนวนลอย (และในบางภาษา BigInts ที่มีความแม่นยำอย่างต่อเนื่อง)


1
ฉันไม่เห็นด้วยกับประโยคนี้ - "ในภาษาที่พิมพ์แบบคงที่ประเภทของตัวแปรและพารามิเตอร์ทั้งหมดจะต้องประกาศในแหล่งที่มา" - ใน SML ประเภทของตัวแปรไม่จำเป็นต้องประกาศ (วิธีตรวจสอบพวกเขา) ช่วยให้ฟังก์ชั่นการพูดfจะเกิดการโต้แย้งx( fun f(x)) [** เพื่อไม่ให้มีการประกาศประเภท **] x+1และร่างกายของฟังก์ชั่น หากไม่มีประเภทคอมไพเลอร์ที่ประกาศจะคิดออกว่าxจะต้องมี int - fun f x = x + 1; val f = fn : int -> int
Filip Bartuzi

เกี่ยวกับ C, หล่อไม่ได้ต่อต้านการพิมพ์ที่แข็งแกร่ง แต่ C ช่วยให้สำหรับการเพิ่มประเภทที่แตกต่างกันได้โดยไม่ต้องหล่อมากเกินไปเช่น:5 + 'c' // OK
เมห์เม็ต

3
@mehmet: ใน C ค่าอักขระอยู่ในโดเมนเลขจำนวนเต็มดังนั้นตัวอย่างเฉพาะไม่ได้ละเมิดความปลอดภัยของประเภท 'c' เป็นเพียงน้ำตาลประโยคสำหรับ 99. C ไม่มีประเภทอักขระเฉพาะ
Peter Lewerin

Peter Lewerin: ถูกต้องฉันควรยกตัวอย่างที่ดีกว่า แต่น่าเสียดายที่จะได้รับเกือบ 20 ปีตั้งแต่ฉันไม่ได้สัมผัส C :)
เมห์เม็ต

1
C ไม่ได้เป็นภาษาพิมพ์อย่างอ่อน มันเป็นเพียงแค่ว่า Java, C # ฯลฯ เป็นภาษาที่มีการพิมพ์มากขึ้นเมื่อเทียบกับ C. อ่านเพิ่มเติมได้ที่นี่ - en.wikipedia.org/wiki/Strong_and_weak_typing หากคุณตรวจสอบคำจำกัดความของภาษาที่พิมพ์ "อ่อนแอ" แล้ว "อ่อนแอ" ภาษาที่พิมพ์ เป็นสิ่งที่คุณสามารถทำการแปลงรูปแบบใด ๆ ได้ตัวอย่างเช่น int สามารถ"แปลง"หรือแปลงเป็นสตริงได้โดยปริยายตอนนี้คิดว่าตัวเองว่าสิ่งนี้เป็นไปได้ใน C หรือไม่?
hagrawal

15

วันนี้การวิจัยเกี่ยวกับเรื่องนี้ฉันมาข้ามบทความดีดีนี้http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.htmlมันล้างขึ้นจำนวนมาก สิ่งต่าง ๆ สำหรับฉันและฉันคิดว่าอาจเพิ่มคำตอบที่ดีบางข้อด้านบน

พิมพ์ดีดแข็งแรงและอ่อนแอ:

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

ประเภทคงที่และแบบไดนามิก

นี่เป็นเพียงการจำแนกประเภททั่วไปของระบบพิมพ์ที่มีความหมายที่แท้จริง ตามความเป็นจริงมันเป็นเรื่องสำคัญที่มักจะมีการประมาณต่ำกว่า [... ] ระบบการพิมพ์แบบไดนามิกและแบบคงที่เป็นสองสิ่งที่แตกต่างกันอย่างสิ้นเชิงซึ่งมีเป้าหมายเกิดขึ้นทับซ้อนกันบางส่วน

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

ประเภทที่ชัดเจน / โดยนัย:

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


8

จากPragmatics ภาษาโปรแกรมของ Scott หน้า 3 รุ่น 291 เรามี

การตรวจสอบประเภทเป็นกระบวนการตรวจสอบให้แน่ใจว่าโปรแกรมปฏิบัติตามกฎความเข้ากันได้ของประเภทภาษา การละเมิดกฎเรียกว่าการปะทะกันของประเภท มีการกล่าวภาษาที่พิมพ์อย่างรุนแรงหากห้ามในลักษณะที่การบังคับใช้ภาษาสามารถบังคับใช้แอปพลิเคชันของการดำเนินการใด ๆ กับวัตถุใด ๆ ที่ไม่ได้มีไว้เพื่อสนับสนุนการดำเนินการนั้น ภาษาถูกกล่าวเพื่อพิมพ์แบบสแตติกถ้าพิมพ์อย่างมากและการตรวจสอบชนิดสามารถดำเนินการในเวลารวบรวม ในความหมายที่เข้มงวดที่สุดของคำนั้นมีเพียงไม่กี่ภาษาที่พิมพ์แบบคงที่ ในทางปฏิบัติเทอร์มินัสมักใช้กับภาษาที่การตรวจสอบประเภทส่วนใหญ่สามารถทำได้ในเวลารวบรวมและส่วนที่เหลือสามารถทำได้ในเวลาทำงาน

ตัวอย่างบางส่วน: Ada ถูกพิมพ์อย่างยิ่งและส่วนใหญ่พิมพ์แบบคงที่ (ข้อ จำกัด บางประเภทจะต้องตรวจสอบในเวลาทำงาน) การใช้ภาษาปาสคาลยังสามารถทำการตรวจสอบประเภทส่วนใหญ่ได้ในเวลารวบรวมแม้ว่าภาษาจะไม่ได้พิมพ์อย่างมาก: บันทึกชุดตัวแปรที่ไม่ได้ติดแท็ก (จะกล่าวถึงในหัวข้อ 7.3.4) เป็นช่องโหว่เท่านั้น C89 นั้นมีความสำคัญมากกว่าภาษาถิ่น แต่ก็ยังพิมพ์น้อยกว่าปาสคาลอย่างมีนัยสำคัญ ช่องโหว่ของมันรวมถึงสหภาพรูทีนย่อยที่มีพารามิเตอร์หลายตัวและการทำงานร่วมกันของพอยน์เตอร์และอาร์เรย์ (จะกล่าวถึงในหัวข้อ 7.7.1) การใช้งานของ C ไม่ค่อยตรวจสอบอะไรในเวลาทำงาน

การตรวจสอบประเภทแบบไดนามิก (รันไทม์) เป็นรูปแบบหนึ่งของการโยงล่าช้าและมีแนวโน้มที่จะพบในภาษาที่ทำให้เกิดปัญหาอื่น ๆ จนกว่าจะถึงเวลารัน Lisp และ Smalltalk นั้นถูกพิมพ์แบบไดนามิก ภาษาสคริปต์ส่วนใหญ่ก็พิมพ์แบบไดนามิกเช่นกัน บางชนิด (เช่น Python และ Ruby) นั้นพิมพ์ออกมาอย่างรุนแรง ภาษาที่มีการกำหนดขอบเขตแบบไดนามิกโดยทั่วไปจะพิมพ์แบบไดนามิก (หรือไม่ได้พิมพ์เลย): หากคอมไพเลอร์ไม่สามารถระบุวัตถุที่ชื่ออ้างถึงได้โดยทั่วไปจะไม่สามารถกำหนดประเภทของวัตถุได้

ดังนั้นในแง่ง่ายการพิมพ์แบบสแตติก / ไดนามิกหมายถึงเวลาที่การตรวจสอบประเภทเกิดขึ้น: เวลารวบรวมสำหรับการพิมพ์แบบคงที่และเวลาทำงานสำหรับภาษาแบบไดนามิก ในทำนองเดียวกันการพิมพ์ที่รัดกุม / อ่อนหมายถึงความก้าวร้าวของภาษาในการบังคับใช้ระบบการพิมพ์

ฉันพยายามแปลคำอธิบายของ Scott เป็นไดอะแกรมที่สวยงามซึ่งฉันได้โพสต์ไว้ด้านล่าง

เครื่องบินแบบคงที่ / ไดนามิก - แข็งแรง / พิมพ์ดีดอ่อนแอ


5

ฉันคิดว่าเพื่อนร่วมงานคนอื่นทำผลงานได้ดี อธิบายความแตกต่างระหว่างการพิมพ์แบบคงที่และแบบไดนามิก แต่สำหรับประเด็นที่เกี่ยวข้องกับการพิมพ์ที่เข้มแข็งและอ่อนแอนั้นควรกล่าวว่ามีความเข้าใจ / มุมมองที่แตกต่างกัน

ที่นี่สองตัวอย่าง:

  • บางคนบอกว่า Haskell พิมพ์อย่างรุนแรงเพราะคุณไม่ได้รับอนุญาตให้ทำการแปลงใด ๆ

  • อื่น ๆ (เช่นมุมมองของ Dario) พูดภาษาที่อนุญาตให้แปลงจากสตริงเป็นตัวเลขโดยมีวัตถุประสงค์ที่จะพิมพ์อย่างอ่อน แต่คนอื่น ๆ เรียกสิ่งนี้ว่าแค่พิมพ์เป็ด

ข้อความทั้งสองเน้นที่ไม่สุดขั้วตรงข้ามของระบบพิมพ์ แต่มีแง่มุมที่แตกต่างกัน ดังนั้นฉันจึงเข้าร่วมมุมมองของ Mr. Ramsey ที่จะไม่ใช้คำว่า "strong" และ "อ่อนแอ" เพื่อแยกความแตกต่างระหว่างระบบประเภท


5

ภาษาที่พิมพ์แบบไดนามิกแบบคงที่ v / s

  • ภาษาที่พิมพ์แบบคงที่คือภาษาที่ทำการพิมพ์การตรวจสอบในเวลารวบรวมดังนั้นนี่ก็หมายความว่าในภาษาที่พิมพ์แบบคงที่ตัวแปรแต่ละตัวจะมีประเภทและไม่เปลี่ยนแปลงตามหลักสูตร ในทางตรงข้ามภาษาที่พิมพ์แบบไดนามิกนั้นเป็นภาษาที่ใช้การตรวจสอบชนิดในขณะทำงานและไม่มีการตรวจสอบประเภท ณ เวลารวบรวมดังนั้นนี่ก็หมายความว่าในภาษาที่พิมพ์แบบไดนามิกอาจมีหรือไม่มีประเภทที่เกี่ยวข้องกับตัวแปรและหากมีการเชื่อมโยงประเภทหนึ่งก็อาจเป็นประเภททั่วไปเช่น“ var” ใน JS ซึ่งถือได้ดีทั้งสตริงและหมายเลข
    • “ การใช้ภาษาที่ตรวจสอบประเภทแบบไดนามิกโดยทั่วไปจะเชื่อมโยงแต่ละวัตถุรันไทม์กับแท็กประเภท (เช่นการอ้างอิงถึงประเภท) ที่มีข้อมูลประเภทของมัน ข้อมูลประเภทรันไทม์ (RTTI) นี้ยังสามารถใช้ในการใช้การจัดส่งแบบไดนามิกการเชื่อมโยงช้าการส่งสัญญาณลงการสะท้อนและคุณสมบัติที่คล้ายกัน”
  • แม้ว่าภาษาจะถูกพิมพ์แบบคงที่ แต่ก็อาจมีคุณสมบัติการพิมพ์แบบไดนามิกซึ่งโดยทั่วไปหมายความว่าการตรวจสอบประเภทบางประเภทที่รันไทม์เช่นกัน สิ่งนี้มีประโยชน์ในการคัดเลือกนักแสดง
    • “ คุณสมบัติภาษาการเขียนโปรแกรมที่มีประโยชน์และทั่วไปไม่สามารถตรวจสอบได้แบบสแตติกเช่นการส่งแบบลง ดังนั้นหลายภาษาจะมีการตรวจสอบทั้งแบบคงที่และแบบไดนามิก ตัวตรวจสอบชนิดคงที่จะตรวจสอบสิ่งที่ทำได้และการตรวจสอบแบบไดนามิกจะตรวจสอบส่วนที่เหลือ”
  • “ บางภาษาอนุญาตให้เขียนรหัสที่ไม่ปลอดภัยสำหรับพิมพ์ ตัวอย่างเช่นใน C โปรแกรมเมอร์สามารถสร้างมูลค่าระหว่างสองประเภทที่มีขนาดเท่ากันได้อย่างอิสระ”
  • ข้อดีของภาษาที่พิมพ์ "แบบคงที่" คือ:
    • เนื่องจากการตรวจสอบประเภทส่วนใหญ่เสร็จสิ้นในเวลารวบรวมเพื่อให้ล่ามหรือรันไทม์สามารถทำงานได้อย่างเต็มความเร็วโดยไม่ต้องกังวลเกี่ยวกับประเภท
    • ซึ่งนำไปสู่จำนวนข้อยกเว้นรันไทม์หรือข้อผิดพลาดที่เกี่ยวข้องกับประเภทน้อยกว่าเนื่องจากการตรวจสอบชนิดส่วนใหญ่เสร็จสิ้นในเวลารวบรวม
  • ข้อดีของภาษาที่พิมพ์ "แบบไดนามิก" คือ:
    • พวกเขาสามารถช่วยในการสร้างต้นแบบที่รวดเร็วมากเนื่องจากนักพัฒนาไม่จำเป็นต้องเข้าใจระบบประเภทดังนั้น dev สามารถสร้างตัวแปรและรันได้อย่างอิสระและสิ่งนี้นำไปสู่การสร้างต้นแบบที่รวดเร็วมาก
  • รายการภาษาที่พิมพ์แบบคงที่และแบบไดนามิก :
    • แบบคงที่:
      • ชวา
      • C (C เป็นภาษาที่พิมพ์แบบสแตติก แต่พิมพ์น้อยลงอย่างมากเมื่อเทียบกับ Java เพราะช่วยให้แปลงได้มากขึ้น)
      • C ++
      • ค#
    • แบบไดนามิก:
      • PERL
      • PHP
      • หลาม
      • JavaScript
      • ทับทิม
  • การตรวจสอบประเภทเป็นคุณสมบัติด้านความปลอดภัยที่สำคัญ สมมติว่าไม่มีการตรวจสอบประเภทและวิธีการรับวัตถุประเภท "BankAccount" ซึ่งมีวิธีการที่เรียกว่า "creditAccount (BankAccountDetails)" ตอนนี้ที่รันไทม์ถ้าไม่มีการตรวจสอบประเภทแล้วฉันสามารถผ่านวัตถุของตัวเอง ระดับซึ่งมีวิธีการเดียวกัน“ creditAccount (BankAccountDetails)” และจะถูกดำเนินการโดยพิจารณาว่าเรากำลังพูดถึงภาษาเชิงวัตถุเพราะ OOP รองรับ“ ความหลากหลาย” และนี่คือสิ่งที่เรากำลังพูดถึงคืออะไร แต่“ ความหลากหลาย” ดังนั้นโดยทั่วไปภาษาเชิงวัตถุ (ซึ่งโดยทั่วไปหมายถึงรองรับ "polymorphism") ซึ่งไม่มีการตรวจสอบที่รัดกุมสามารถนำไปสู่ปัญหาด้านความปลอดภัย

v / s ภาษาที่พิมพ์อ่อนแอมาก

  • ภาษาที่พิมพ์อย่างชัดเจนคือภาษาที่ไม่อนุญาตให้มีการแปลงโดยนัยหากมีการสูญเสียความแม่นยำ ตัวอย่างเช่นใน Java คุณสามารถใช้ "int to long" ได้เนื่องจากไม่มีการสูญเสียความแม่นยำ แต่คุณไม่สามารถ "implantly" ทำการ "long to int" ได้เนื่องจากจะมีการสูญเสียความแม่นยำ ในทางตรงกันข้ามในภาษาที่พิมพ์อย่างอ่อนอนุญาตให้แปลงโดยนัยแม้ว่าจะมีการสูญเสียความแม่นยำ
  • ฉันคิดว่าภาษาที่พิมพ์แบบไดนามิกอาจเป็นภาษาที่พิมพ์ได้อย่างรุนแรงหาก "ที่รันไทม์" ไม่อนุญาตให้มีการแปลงโดยนัยซึ่งมีการสูญเสียความแม่นยำ

อ่านเพิ่มเติมได้ดี


คุณยกมา "ตอนรันไทม์ถ้าไม่มีการตรวจสอบประเภทแล้วฉันสามารถผ่านวัตถุของคลาสของตัวเองซึ่งมีวิธีการเดียวกัน“ creditAccount (BankAccountDetails)” - ถ้าคุณผ่านกลไกที่อาจบล็อกคุณไม่ให้ผ่านวัตถุ แล้วการตรวจสอบประเภทจะหยุดคุณไม่ให้เรียกวิธีนั้นในกรณีของภาษาที่พิมพ์แบบคงที่ได้อย่างไร
Aseem Yadav

@AseemYadav คุณหมายถึงอะไรโดย "* ถ้าคุณผ่านกลไกที่จะบล็อกคุณไม่ให้ผ่านวัตถุ *"
hagrawal

ตามที่คุณกล่าวถึงมันเป็นคุณลักษณะด้านความปลอดภัยที่สำคัญและคุณสามารถส่งวัตถุของคลาสของคุณด้วยวิธีการเดียวกันดังนั้นจึงบอกเป็นนัยว่าดูเหมือนว่าช่องโหว่เมื่อคุณพยายามที่จะเจาะรหัสของคนอื่นและ หากคุณกำลังพูดในบริบทของรหัสที่เป็นของคุณมากกว่าปัญหาด้านประสิทธิภาพมากกว่าความปลอดภัยที่เกี่ยวข้อง
Aseem Yadav

ไม่มีแง่มุมด้านประสิทธิภาพของมันคุณต้องดูจากบริบทของความหลากหลายแล้วคุณจะสามารถเข้าใจด้านความปลอดภัยของมันฉันได้กล่าวถึงเรื่องนี้ในวรรคเดียวกัน
hagrawal

1

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

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

องค์ประกอบของภาษาที่พิมพ์แบบคงที่และแบบไดนามิกสามารถรวมกันได้ ตัวอย่างเช่น C # รองรับตัวแปรที่พิมพ์ทั้งแบบคงที่และแบบไดนามิกและภาษาเชิงวัตถุจะสนับสนุนลำดับชั้นของประเภท ภาษาที่พิมพ์แบบคงที่มักจะให้วิธีการต่าง ๆ ในการข้ามการตรวจสอบชนิดเช่นโดยใช้การแคสต์การสะท้อนและการร้องขอแบบไดนามิก

การเปรียบเทียบกับ Strong Weak Typing หมายถึงความต่อเนื่องของภาษาที่พยายามป้องกันข้อบกพร่องเนื่องจากใช้ตัวแปรราวกับว่าเป็นประเภทหนึ่งเมื่อเป็นประเภทอื่น ตัวอย่างเช่นทั้ง C และ Java เป็นภาษาที่พิมพ์แบบสแตติกอย่างไรก็ตาม Java ใช้การตรวจสอบประเภทที่แข็งแกร่งกว่า C รหัส C ต่อไปนี้มีความสุขในการคอมไพล์และเรียกใช้และจะใส่ค่าแบบสุ่มลงในตัวแปร b ที่รันไทม์ ข้อผิดพลาด:

char *a = "123";
int b = (int)a;

โค้ด Java ที่เทียบเท่าจะสร้างข้อผิดพลาดในการคอมไพล์ซึ่งโดยทั่วไปจะดีกว่า:

String a = "123"
int b = (int)a;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.