Sự khác biệt giữa các ngôn ngữ gõ tĩnh và gõ động là gì?


946

Tôi nghe nhiều ngôn ngữ lập trình mới được gõ động nhưng thực sự nó có nghĩa gì khi chúng ta nói một ngôn ngữ được gõ động so với gõ tĩnh?


25
Câu hỏi hay nhưng câu trả lời được chấp nhận của bạn không phải là câu trả lời đúng.
Jon Harrop

42
bạn có thể xin vui lòng tham khảo một cái gì đó là chính xác sau đó?
Sagiruddin Thứ Hai

@EricLeschinski Tôi nghĩ bây giờ các bài kiểm tra đơn vị đã giúp giải quyết vấn đề đó và các ngôn ngữ được gõ động như JavaScript có thể được mã hóa để đảm bảo rằng nó sẽ giữ được, do đó, nó có đủ điều kiện để phát triển phần mềm doanh nghiệp không, bạn có nghĩ vậy không?
pixel 67

8
Tốt nhất, các bài kiểm tra đơn vị xấu đi theo thời gian và bị tắt bởi các đồng nghiệp cố gắng tăng cường bảo mật công việc, tệ nhất, họ không bao giờ được viết ngay từ đầu. Nó giống như đề nghị với một thợ cơ khí chuyên nghiệp sử dụng băng keo trên xe ô tô của khách hàng của mình. Có đàn em, sử dụng băng keo trong công việc truyền tải này là một ý tưởng tốt ... cho bạn.
Eric Leschinski

2
Tôi biết câu hỏi này đã 10 tuổi, nhưng từ những gì tôi đọc được trong các bình luận, có lẽ bạn nên chuyển sang chấp nhận câu trả lời từ "Christopher Tokar".
Rev1.0

Câu trả lời:


854

Ngôn ngữ gõ tĩnh

Một ngôn ngữ được gõ tĩnh nếu loại biến được biết tại thời điểm biên dịch. Đối với một số ngôn ngữ, điều này có nghĩa là bạn là lập trình viên phải chỉ định loại biến của từng biến (ví dụ: Java, C, C ++); các ngôn ngữ khác cung cấp một số dạng suy luận kiểu , khả năng của hệ thống loại để suy ra loại biến (ví dụ: OCaml, Haskell, Scala, Kotlin)

Ưu điểm chính ở đây là tất cả các loại kiểm tra có thể được thực hiện bởi trình biên dịch, và do đó rất nhiều lỗi nhỏ bị bắt gặp ở giai đoạn rất sớm.

Ví dụ: C, C ++, Java, Rust, Go, Scala

Ngôn ngữ gõ động

Một ngôn ngữ được gõ động nếu loại được liên kết với các giá trị thời gian chạy và không được đặt tên biến / trường / vv. Điều này có nghĩa là bạn là một lập trình viên có thể viết nhanh hơn một chút vì bạn không phải chỉ định các loại mỗi lần (trừ khi sử dụng ngôn ngữ gõ tĩnh với suy luận kiểu ).

Ví dụ: Perl, Ruby, Python, PHP, JavaScript

Hầu hết các ngôn ngữ script đều có tính năng này vì dù sao cũng không có trình biên dịch để kiểm tra kiểu tĩnh, nhưng bạn có thể thấy mình đang tìm kiếm một lỗi do trình thông dịch hiểu sai loại biến. May mắn thay, các kịch bản có xu hướng nhỏ để các lỗi không có nhiều nơi để ẩn.

Hầu hết các ngôn ngữ được gõ động đều cho phép bạn cung cấp thông tin loại, nhưng không yêu cầu. Một ngôn ngữ hiện đang được phát triển, Rascal , sử dụng cách tiếp cận hỗn hợp cho phép nhập động trong các hàm nhưng thực thi gõ tĩnh cho chữ ký hàm.


6
@NomeN Bạn có thể đặt tên cho bất kỳ ngôn ngữ được gõ động nào thực hiện suy luận kiểu HM không?
Pete Kirkham

88
"Một ngôn ngữ được gõ động nếu loại biến được diễn giải trong thời gian chạy": Không. Một ngôn ngữ được gõ động nếu loại được liên kết với các giá trị thời gian chạy và không được đặt tên biến / trường / v.v.
Paul Biggar

15
Không chính xác, gõ tĩnh có nghĩa là "giá trị tham chiếu rõ ràng (không giống với thời gian biên dịch) bị ràng buộc đối với loại giá trị mà nó có thể biểu thị và việc triển khai ngôn ngữ, cho dù đó là trình biên dịch hay trình thông dịch , cả hai đều thi hành và sử dụng những ràng buộc này càng nhiều càng tốt. " được trích dẫn từ: c2.com/cgi/wiki?StaticTyping mà, cách tôi hiểu nó, là chính xác.
Sói Matthias

6
Điều rõ ràng nhất về các hệ thống kiểu Java, C, C ++, Pascal và nhiều ngôn ngữ khác được sử dụng rộng rãi của các ngành công nghiệp khác không phải là chúng được gõ tĩnh mà là chúng được gõ rõ ràng. Nói cách khác, chúng đòi hỏi rất nhiều khai báo kiểu. (Trong thế giới của các ngôn ngữ ít được gõ rõ ràng, trong đó các khai báo này là tùy chọn, chúng thường được gọi là các chú thích kiểu kiểu Cameron.) Điều này không liên quan gì đến các kiểu tĩnh. tiếp tục ..
Vipresh

7
Các ngôn ngữ gõ tĩnh đầu tiên được gõ rõ ràng bởi sự cần thiết. Tuy nhiên, các thuật toán suy luận kiểu - các kỹ thuật để xem mã nguồn hoàn toàn không có khai báo kiểu và quyết định loại biến nào của nó đã tồn tại trong nhiều năm nay. Ngôn ngữ ML, sử dụng nó. Haskell, cải thiện nó, bây giờ là khoảng 15 tuổi. Ngay cả C # hiện cũng đang áp dụng ý tưởng này, điều này sẽ khiến nhiều người chú ý và chắc chắn sẽ đưa ra những tuyên bố về việc nó bị đánh bại một cách yếu ớt. tiếp tục ...
Vipresh

399

Các ngôn ngữ lập trình được gõ tĩnh thực hiện kiểm tra kiểu (tức là quá trình xác minh và thực thi các ràng buộc của các loại) tại thời gian biên dịch trái ngược với thời gian chạy .

Các ngôn ngữ lập trình được gõ động thực hiện kiểm tra kiểu vào thời gian chạy trái ngược với thời gian biên dịch .

Ví dụ về các ngôn ngữ được nhập tĩnh là: - Java, C, C ++

Ví dụ về các ngôn ngữ được nhập động là: - Perl, Ruby, Python, PHP, JavaScript


19
Tôi nghĩ rằng đây là câu trả lời tốt nhất. Cụ thể, câu trả lời được chấp nhận phần lớn là không chính xác.
Jon Harrop

1
@JonHarrop Theo những cách cụ thể?
1252748

21
@thomas: "Điều này có nghĩa là bạn là một lập trình viên có thể viết nhanh hơn một chút vì bạn không phải chỉ định loại mọi lúc". Bạn không phải chỉ định loại mỗi lần với kiểu gõ tĩnh nếu bạn có kiểu suy luận. Xem SML, OCaml, F #, Haskell ...
Jon Harrop

1
Trong các ngôn ngữ prog gõ tĩnh, việc kiểm tra kiểu được thực hiện trước thời gian chạy, nhưng không chính xác tại thời gian biên dịch.
Luiz Felipe

307

Dưới đây là một ví dụ tương phản với cách Python (gõ động) và Go (gõ tĩnh) xử lý lỗi loại:

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

Python thực hiện kiểm tra kiểu trong thời gian chạy và do đó:

silly(2)

Chạy hoàn toàn tốt, và tạo ra đầu ra dự kiến Hi. Lỗi chỉ được nêu ra nếu dòng có vấn đề bị tấn công:

silly(-1)

Sản xuất

TypeError: unsupported operand type(s) for +: 'int' and 'str'

bởi vì dòng liên quan đã thực sự được thực thi.

Mặt khác, kiểm tra kiểu tại thời gian biên dịch:

package main

import ("fmt"
)

func silly(a int) {
    if (a > 0) {
        fmt.Println("Hi")
    } else {
        fmt.Println("3" + 5)
    }
}

func main() {
    silly(2)
}

Ở trên sẽ không biên dịch, với lỗi sau:

invalid operation: "3" + 5 (mismatched types string and int)

5
Cảm ơn ví dụ gọn gàng. Vì vậy, tôi suy luận rằng tất cả các ngôn ngữ kịch bản được gõ động, vì chúng không được biên dịch?
CᴴᴀZ

8
Đúng. tất cả các ngôn ngữ script được gõ động, bởi vì chúng không phải là trình biên dịch để kiểm tra kiểu tĩnh. Điểm này đã được minh họa trong bài viết này sitepoint.com/typing-versus-dynamic-typing .
Shashi

9
Scala có thể được sử dụng làm ngôn ngữ kịch bản và nó được gõ tĩnh! #discussion @Shashi
Sagiruddin Thứ Hai

3
@Shashi Compilation không có nghĩa là gõ tĩnh. Haskell có thể được giải thích với runhaskell, ví dụ.
BalinKingOfMoria Tái lập CM

2
Ngoài ra ngôn ngữ Scripting KHÔNG có nghĩa là ngôn ngữ được giải thích. TypeScript được gõ tĩnh, biên dịch / dịch mã, nhưng ngôn ngữ kịch bản.
metalim

161

Đơn giản chỉ cần đặt nó theo cách này: trong các loại biến ngôn ngữ được gõ tĩnhtĩnh , nghĩa là một khi bạn đặt biến thành một loại, bạn không thể thay đổi nó. Đó là bởi vì gõ được liên kết với biến chứ không phải giá trị mà nó đề cập đến.

Ví dụ trong Java:

String str = "Hello";  //variable str statically typed as string
str = 5;               //would throw an error since str is supposed to be a string only

Mặt khác: trong các loại biến ngôn ngữ được gõ độngđộng , nghĩa là sau khi bạn đặt biến thành một loại, bạn CÓ THỂ thay đổi nó. Đó là bởi vì gõ được liên kết với giá trị mà nó giả định chứ không phải là chính biến.

Ví dụ trong Python:

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

Vì vậy, tốt nhất là nghĩ về các biến trong các ngôn ngữ được gõ động như chỉ là các con trỏ chung cho các giá trị được gõ.

Để tổng hợp, mô tả (hoặc nên mô tả) các biến trong ngôn ngữ chứ không phải chính ngôn ngữ. Nó có thể được sử dụng tốt hơn như một ngôn ngữ với các biến được gõ tĩnh so với ngôn ngữ có các biến được gõ động IMHO.

Các ngôn ngữ được nhập tĩnh thường là các ngôn ngữ được biên dịch, do đó, trình biên dịch kiểm tra các loại (có ý nghĩa hoàn hảo phải không? Vì các loại không được phép thay đổi sau này trong thời gian chạy).

Các ngôn ngữ được gõ động thường được diễn giải, do đó việc kiểm tra kiểu (nếu có) xảy ra vào thời gian chạy khi chúng được sử dụng. Điều này tất nhiên mang lại một số chi phí hiệu năng và là một trong những lý do khiến các ngôn ngữ động (ví dụ: python, ruby, php) không có quy mô tốt như các ngôn ngữ được nhập (java, c #, v.v.). Từ góc độ khác, các ngôn ngữ gõ tĩnh có nhiều chi phí khởi nghiệp: khiến bạn thường viết nhiều mã hơn, mã khó hơn. Nhưng điều đó trả tiền sau.

Điều tốt là cả hai bên đều mượn các tính năng từ phía bên kia. Các ngôn ngữ được nhập đang kết hợp nhiều tính năng động hơn, ví dụ: chung và thư viện động trong c # và các ngôn ngữ động bao gồm kiểm tra loại nhiều hơn, ví dụ: chú thích loại trong python hoặc biến thể HACK của PHP, thường không phải là cốt lõi của ngôn ngữ và có thể sử dụng được trên nhu cầu.

Khi nói đến lựa chọn công nghệ, không bên nào có ưu thế nội tại hơn bên kia. Đây chỉ là vấn đề ưu tiên cho dù bạn muốn kiểm soát nhiều hơn hay bắt đầu linh hoạt. chỉ cần chọn công cụ phù hợp cho công việc và đảm bảo kiểm tra những gì có sẵn trong điều ngược lại trước khi xem xét một công tắc.


8
Điều này làm cho rất nhiều ý nghĩa. Tôi nghĩ rằng nó giải thích ít nhất là lý do đằng sau những cái tên tốt hơn nhiều so với các câu trả lời khác ở đây.
JamEngulfer

Theo tài liệu tham khảo này Python là một ngôn ngữ được gõ tĩnh và gõ động: wiki.python.org/moin/ mẹo Có ai biết tại sao không?
modulitos

1
Lucas, ngược lại, tài liệu cứ lặp đi lặp lại rằng Python vừa được gõ mạnh mẽ vừa năng động. Bạn đã thấy điều đó ở đâu? Bạn có thể trích dẫn?
mehmet

2
Tôi nghĩ rằng câu trả lời này truyền đạt tốt nhất các khái niệm theo cách đơn giản nhất. Rất nhiều câu trả lời khác cố gắng mô tả trừu tượng khái niệm này, nhưng thất bại ở một số chi tiết. Tôi thà thấy câu trả lời này ở đầu danh sách.
Hawkeye

5
Hầu hết các câu trả lời khác tạo ra nhiều câu hỏi trong tâm trí của tôi. Điều này đã xóa tất cả chúng. Câu trả lời này thực sự nên có ở đầu IMHO
Hami Torun

39

http://en.wikipedia.org/wiki/Type_system

Gõ tĩnh

Một ngôn ngữ lập trình được cho là sử dụng kiểu gõ tĩnh khi kiểm tra kiểu được thực hiện trong thời gian biên dịch trái ngược với thời gian chạy. Trong kiểu gõ tĩnh, các kiểu được liên kết với các biến không phải là giá trị. Các ngôn ngữ được nhập tĩnh bao gồm Ada, C, C ++, C #, JADE, Java, Fortran, Haskell, ML, Pascal, Perl (liên quan đến việc phân biệt vô hướng, mảng, băm và chương trình con) và Scala. Gõ tĩnh là một hình thức xác minh chương trình giới hạn (xem loại an toàn): theo đó, nó cho phép nhiều lỗi loại được phát hiện sớm trong chu kỳ phát triển. Trình kiểm tra loại tĩnh chỉ đánh giá thông tin loại có thể được xác định tại thời điểm biên dịch, nhưng có thể xác minh rằng các điều kiện đã kiểm tra giữ cho tất cả các lần thực hiện có thể của chương trình, giúp loại bỏ sự cần thiết phải lặp lại kiểm tra loại mỗi khi chương trình được thực thi. Việc thực hiện chương trình cũng có thể được thực hiện hiệu quả hơn (tức là nhanh hơn hoặc giảm bộ nhớ) bằng cách bỏ qua kiểm tra loại thời gian chạy và cho phép tối ưu hóa khác.

Bởi vì họ đánh giá thông tin loại trong quá trình biên dịch và do đó thiếu thông tin loại chỉ có sẵn trong thời gian chạy, nên trình kiểm tra loại tĩnh là bảo thủ. Họ sẽ từ chối một số chương trình có thể hoạt động tốt trong thời gian chạy, nhưng điều đó không thể được xác định một cách tĩnh để được đánh máy tốt. Ví dụ: ngay cả khi một biểu thức luôn luôn đánh giá là đúng trong thời gian chạy, một chương trình chứa mã

if <complex test> then 42 else <type error>

sẽ bị từ chối khi nhập sai, vì phân tích tĩnh không thể xác định rằng nhánh khác sẽ không được thực hiện. [1] Hành vi bảo thủ của trình kiểm tra loại tĩnh là thuận lợi khi đánh giá sai không thường xuyên: Trình kiểm tra loại tĩnh có thể phát hiện lỗi loại trong các đường dẫn mã hiếm khi được sử dụng. Nếu không kiểm tra kiểu tĩnh, ngay cả các kiểm tra phạm vi mã với độ bao phủ mã 100% có thể không thể tìm thấy các lỗi loại đó. Các thử nghiệm bảo hiểm mã có thể không phát hiện ra các lỗi loại như vậy bởi vì sự kết hợp của tất cả các vị trí nơi các giá trị được tạo và tất cả các vị trí sử dụng một giá trị nhất định phải được tính đến.

Các ngôn ngữ gõ tĩnh được sử dụng rộng rãi nhất không phải là loại chính thức an toàn. Chúng có "lỗ hổng" trong đặc tả ngôn ngữ lập trình cho phép các lập trình viên viết mã phá vỡ xác minh được thực hiện bởi trình kiểm tra kiểu tĩnh và do đó giải quyết một loạt các vấn đề. Ví dụ, Java và hầu hết các ngôn ngữ kiểu C đều có kiểu xảo quyệt và Haskell có các tính năng như unsafePerformIO: các hoạt động đó có thể không an toàn khi chạy, vì chúng có thể gây ra hành vi không mong muốn do nhập sai giá trị khi chương trình chạy.

Gõ động

Một ngôn ngữ lập trình được cho là được gõ động, hoặc chỉ là 'động', khi phần lớn việc kiểm tra kiểu của nó được thực hiện vào thời gian chạy trái ngược với thời gian biên dịch. Trong kiểu gõ động, các kiểu được liên kết với các giá trị không phải là biến. Các ngôn ngữ được nhập động bao gồm Groovy, JavaScript, Lisp, Lua, Objective-C, Perl (đối với các loại do người dùng xác định nhưng không phải là các loại tích hợp), PHP, Prolog, Python, Ruby, Smalltalk và Tcl. So với gõ tĩnh, gõ động có thể linh hoạt hơn (ví dụ: bằng cách cho phép các chương trình tạo các loại và chức năng dựa trên dữ liệu thời gian chạy), mặc dù chi phí ít hơn một đảm bảo tiên nghiệm. Điều này là do một ngôn ngữ gõ động chấp nhận và cố gắng thực thi một số chương trình có thể bị quy định là không hợp lệ bởi trình kiểm tra loại tĩnh.

Gõ động có thể dẫn đến lỗi loại thời gian chạy, đó là, trong thời gian chạy, một giá trị có thể có loại không mong muốn và một thao tác vô nghĩa đối với loại đó được áp dụng. Hoạt động này có thể xảy ra rất lâu sau khi xảy ra lỗi lập trình, đó là nơi mà loại dữ liệu sai được truyền vào một nơi không nên có. Điều này làm cho lỗi khó xác định vị trí.

Các hệ thống ngôn ngữ được gõ động, so với các anh em họ gõ tĩnh của chúng, thực hiện kiểm tra "thời gian biên dịch" ít hơn trên mã nguồn (ví dụ, sẽ kiểm tra xem chương trình có đúng về mặt cú pháp không). Kiểm tra thời gian chạy có thể có khả năng phức tạp hơn, vì chúng có thể sử dụng thông tin động cũng như bất kỳ thông tin nào có trong quá trình biên dịch. Mặt khác, kiểm tra thời gian chạy chỉ xác nhận rằng các điều kiện giữ trong một thực thi cụ thể của chương trình và các kiểm tra này được lặp lại cho mỗi lần thực hiện chương trình.

Phát triển trong các ngôn ngữ gõ động thường được hỗ trợ bởi các thực tiễn lập trình như kiểm tra đơn vị. Kiểm thử là một thông lệ quan trọng trong phát triển phần mềm chuyên nghiệp và đặc biệt quan trọng trong các ngôn ngữ được gõ động. Trong thực tế, kiểm tra được thực hiện để đảm bảo hoạt động chương trình chính xác có thể phát hiện phạm vi lỗi rộng hơn nhiều so với kiểm tra kiểu tĩnh, nhưng ngược lại không thể tìm kiếm toàn diện các lỗi mà cả kiểm tra và kiểm tra loại tĩnh đều có thể phát hiện. Kiểm thử có thể được tích hợp vào chu trình xây dựng phần mềm, trong trường hợp đó có thể được coi là kiểm tra "thời gian biên dịch", trong đó người dùng chương trình sẽ không phải chạy thủ công các kiểm tra đó.

Người giới thiệu

  1. Xỏ, Benjamin (2002). Các loại và ngôn ngữ lập trình. Báo chí MIT. SỐ 0-262-16209-1.

75
Ý tưởng chính của SO là xây dựng một khối kiến ​​thức, không cung cấp liên kết đến những nơi khác. Bạn nên cố gắng ít nhất làm một đoạn trích của wiki để trả lời câu hỏi.
NomeN

5
Nó chỉ có vẻ dư thừa vì nó là một liên kết đến wikipedia chứ không phải một số trang web thoáng qua, nhưng tôi sẽ nhớ điều đó vào lần tới.
Jacob

2
bằng cách nào đó tôi vẫn không thể nghĩ ra một ví dụ trong một ngôn ngữ được gõ động, trong đó một kiểu không rõ ràng trong thời gian biên dịch mà phải được tìm ra khi chạy. Bạn có thể cung cấp cho tôi một số?
Novellizator

3
@Novellizator Nhận xét cũ nhưng hãy tưởng tượng một kịch bản trong đó một số dữ liệu được lấy từ một máy chủ từ xa thì dữ liệu đó được sử dụng để chọn một thuộc tính khỏi một đối tượng. Vd : myObject[remoteDataName]. Sau đó, không có cách nào để biết nó sẽ chọn tài sản nào hoặc thậm chí nếu đó là một tài sản hợp lệ.
Mike Cluck

14

Thuật ngữ "gõ động" không may bị sai. Tất cả các ngôn ngữ được gõ tĩnh và các loại là thuộc tính của biểu thức (không phải là giá trị như một số người nghĩ). Tuy nhiên, một số ngôn ngữ chỉ có một loại. Chúng được gọi là ngôn ngữ uni-gõ. Một ví dụ về ngôn ngữ như vậy là phép tính lambda chưa được kiểm tra.

Trong phép tính lambda chưa được đánh dấu, tất cả các thuật ngữ là thuật ngữ lambda và thao tác duy nhất có thể được thực hiện theo một thuật ngữ là áp dụng nó cho một thuật ngữ khác. Do đó, tất cả các hoạt động luôn dẫn đến đệ quy vô hạn hoặc thuật ngữ lambda, nhưng không bao giờ báo hiệu lỗi.

Tuy nhiên, nếu chúng ta tăng số phép tính lambda chưa được xử lý bằng số nguyên thủy và phép toán số học, thì chúng ta có thể thực hiện các phép toán vô nghĩa, như vậy thêm hai thuật ngữ lambda lại với nhau : (λx.x) + (λy.y). Người ta có thể lập luận rằng điều duy nhất cần làm là báo hiệu lỗi khi điều này xảy ra, nhưng để có thể làm điều này, mỗi giá trị phải được gắn thẻ với một chỉ báo cho biết thuật ngữ đó là thuật ngữ lambda hay số. Sau đó, toán tử bổ sung sẽ kiểm tra xem thực sự cả hai đối số được gắn thẻ là số và nếu chúng không, báo hiệu lỗi. Lưu ý rằng các thẻ này không phải là loại, vì loại là thuộc tính của chương trình, không phải giá trị được tạo bởi các chương trình đó.

Một ngôn ngữ chưa được gõ mà thực hiện điều này được gọi là gõ động.

Các ngôn ngữ như JavaScript, Python và Ruby đều không được gõ. Một lần nữa, typeoftoán tử trong JavaScript và typehàm trong Python có các tên sai; chúng trả về các thẻ được liên kết với toán hạng, không phải kiểu của chúng. Tương tự, dynamic_casttrong C ++ và instanceoftrong Java không thực hiện kiểm tra kiểu.


7

Biên dịch so với phiên dịch

"Khi mã nguồn được dịch"

  • Mã nguồn : gốc (thường được con người nhập vào máy tính)
  • Dịch : Chuyển đổi mã nguồn thành thứ mà máy tính có thể đọc (ví dụ mã máy)
  • Thời gian chạy : Khoảng thời gian khi chương trình đang thực thi các lệnh (sau khi biên dịch, nếu được biên dịch)
  • Ngôn ngữ biên dịch : Mã được dịch trước thời gian chạy
  • Ngôn ngữ được giải thích : Mã được dịch khi đang bay, trong khi thực hiện

Đánh máy

"Khi các loại được kiểm tra"

5 + '3'là một ví dụ về lỗi loại trong các ngôn ngữ được gõ mạnh như Go và Python, vì chúng không cho phép "ép buộc kiểu" -> khả năng giá trị thay đổi loại trong các ngữ cảnh nhất định như hợp nhất hai loại. Các ngôn ngữ được gõ yếu , chẳng hạn như JavaScript, sẽ không gây ra lỗi loại (kết quả là '53').

  • Tĩnh : Các loại được kiểm tra trước thời gian chạy
  • Động : Các loại được kiểm tra khi đang bay, trong khi thực hiện

Các định nghĩa của "Tĩnh & Biên dịch" và "Động & Giải thích" khá giống nhau ... nhưng hãy nhớ đó là "khi các loại được kiểm tra" so với "khi mã nguồn được dịch".

Bạn sẽ nhận được các lỗi cùng loại bất kể ngôn ngữ được biên dịch hay giải thích ! Bạn cần tách các thuật ngữ này về mặt khái niệm.


Ví dụ về Python

Năng động, diễn giải

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

silly(2)

Vì Python được giải thích và gõ động, nên nó chỉ dịch và kiểm tra loại mã mà nó đang thực thi. Các elsekhối không bao giờ thực hiện, vì vậy 5 + '3'thậm chí không bao giờ nhìn vào!

Điều gì nếu nó được gõ tĩnh?

Một lỗi loại sẽ được ném trước khi mã thậm chí chạy. Nó vẫn thực hiện kiểm tra kiểu trước thời gian chạy mặc dù nó được diễn giải.

Nếu nó được biên soạn thì sao?

Các elsekhối sẽ được dịch / nhìn trước khi thời gian chạy, nhưng bởi vì nó tự động gõ nó sẽ không ném ra một lỗi! Các ngôn ngữ được nhập động không kiểm tra các loại cho đến khi thực thi và dòng đó không bao giờ thực thi.


Đi ví dụ

Tĩnh, Biên dịch

package main

import ("fmt"
)

func silly(a int) {
  if (a > 0) {
      fmt.Println("Hi")
  } else {
      fmt.Println("3" + 5)
  }
}

func main() {
  silly(2)
}

Các loại được kiểm tra trước khi chạy (tĩnh) và lỗi loại ngay lập tức bị bắt! Các loại vẫn sẽ được kiểm tra trước thời gian chạy nếu nó được diễn giải, có cùng kết quả. Nếu nó là động, nó sẽ không đưa ra bất kỳ lỗi nào mặc dù mã sẽ được xem xét trong quá trình biên dịch.


Hiệu suất

Một ngôn ngữ được biên dịch sẽ có hiệu suất tốt hơn trong thời gian chạy nếu nó được nhập tĩnh (so với động); kiến thức về các loại cho phép tối ưu hóa mã máy.

Các ngôn ngữ được nhập tĩnh có hiệu suất tốt hơn vào thời gian chạy về bản chất do không cần phải kiểm tra các loại động trong khi thực thi (nó kiểm tra trước khi chạy).

Tương tự, các ngôn ngữ được biên dịch sẽ nhanh hơn trong thời gian chạy vì mã đã được dịch thay vì cần phải "diễn giải" / dịch nó một cách nhanh chóng.

Lưu ý rằng cả hai ngôn ngữ được biên dịch và gõ tĩnh sẽ có độ trễ trước khi chạy để dịch và kiểm tra kiểu, tương ứng.


Khác biệt hơn

Gõ tĩnh bắt lỗi sớm, thay vì tìm thấy chúng trong khi thực hiện (đặc biệt hữu ích cho các chương trình dài). Điều "nghiêm ngặt" hơn ở chỗ nó sẽ không cho phép lỗi loại ở bất cứ đâu trong chương trình của bạn và thường ngăn các biến thay đổi loại, điều này sẽ bảo vệ chống lại các lỗi không mong muốn.

num = 2
num = '3' // ERROR

Gõ động là linh hoạt hơn, mà một số đánh giá cao. Nó thường cho phép các biến thay đổi các loại, điều này có thể dẫn đến các lỗi không mong muốn.


" Bởi vì Python được giải thích và gõ động, nên nó chỉ dịch và kiểm tra loại mã mà nó đang thực thi " - thực sự không phải vậy. Python (ít nhất là triển khai tham chiếu) biên dịch tất cả mã của bạn tại thời điểm nhập (bạn cũng có thể biên dịch các mô-đun trước / mà không cần nhập chúng). Trình biên dịch giới thiệu các tối ưu hóa khác nhau (ít nhất là theo bản chất động của Python cho phép).
Eli Korvigo

6

Các ngôn ngữ được nhập tĩnh : từng biến và biểu thức đã được biết đến tại thời điểm biên dịch.

( int a;a chỉ có thể lấy các giá trị kiểu số nguyên khi chạy)

Ví dụ: C, C ++, Java

Các ngôn ngữ được nhập động : các biến có thể nhận các giá trị khác nhau trong thời gian chạy và loại của chúng được xác định khi chạy.

( var a;a có thể lấy bất kỳ loại giá trị nào trong thời gian chạy)

Ví dụ: Ruby, Python.


5

Kiểm tra loại ngôn ngữ gõ tĩnh tại thời gian biên dịch và loại KHÔNG thể thay đổi. (Đừng dễ thương với các nhận xét kiểu, một biến / tham chiếu mới được tạo).

Kiểm tra loại ngôn ngữ được gõ động vào thời gian chạy và loại biến có thể được thay đổi vào thời gian chạy.


4

Các định nghĩa đơn giản và ngọt ngào, nhưng phù hợp với nhu cầu: Các ngôn ngữ được nhập tĩnh liên kết loại với một biến cho toàn bộ phạm vi của nó (Seg: SCALA) Các ngôn ngữ được gõ động liên kết loại với giá trị thực được tham chiếu bởi một biến.


3
  • Trong một ngôn ngữ gõ tĩnh, một biến được liên kết với một loại được biết đến tại thời điểm biên dịch và loại đó không thay đổi trong suốt quá trình thực hiện chương trình. Tương tự, biến chỉ có thể được gán một giá trị là một thể hiện của loại đã biết / được chỉ định.
  • Trong một ngôn ngữ được gõ động, một biến không có loại và giá trị của nó trong quá trình thực thi có thể là bất kỳ hình dạng và hình dạng nào.

2

Các ngôn ngữ được nhập tĩnh như C ++, Java và các ngôn ngữ được nhập động như Python chỉ khác nhau về cách thực hiện loại biến. Các ngôn ngữ được nhập tĩnh có kiểu dữ liệu tĩnh cho biến, ở đây, kiểu dữ liệu được kiểm tra trong quá trình biên dịch nên việc gỡ lỗi đơn giản hơn nhiều ... trong khi các ngôn ngữ được gõ động không làm như vậy, kiểu dữ liệu được kiểm tra để thực thi chương trình và do đó gỡ lỗi là một chút khó khăn.

Hơn nữa, chúng có một sự khác biệt rất nhỏ và có thể liên quan đến các ngôn ngữ được gõ mạnhgõ yếu . Một ngôn ngữ được gõ mạnh không cho phép bạn sử dụng một loại như một ngôn ngữ khác, vd. C và C ++ ... trong khi các ngôn ngữ được gõ yếu cho phép eg.python


2

Gõ tĩnh

Các loại được kiểm tra trước thời gian chạy để có thể bắt lỗi sớm hơn.

Ví dụ = c ++

Tự động gõ

Các loại được kiểm tra trong khi thực hiện.

Ví dụ = Python


2
Điều này không thực sự thêm bất cứ điều gì chưa được bao phủ bởi các câu trả lời khác, phải không?
Robert

1
Có, nhưng hầu hết các câu trả lời không rõ ràng lắm nên tôi muốn một câu trả lời dễ hiểu.
Atticus Denewmont

1

Các ngôn ngữ gõ tĩnh (trình biên dịch giải quyết các cuộc gọi phương thức và biên dịch các tham chiếu):

  • hiệu suất thường tốt hơn
  • biên dịch lỗi phản hồi nhanh hơn
  • hỗ trợ IDE tốt hơn
  • không phù hợp để làm việc với các định dạng dữ liệu không xác định
  • khó hơn để bắt đầu phát triển khi mô hình không được xác định khi
  • thời gian biên dịch dài hơn
  • trong nhiều trường hợp yêu cầu viết thêm mã

Ngôn ngữ gõ động (quyết định đưa ra trong chương trình đang chạy):

  • hiệu suất thấp hơn
  • phát triển nhanh hơn
  • một số lỗi có thể được phát hiện chỉ sau này trong thời gian chạy
  • tốt cho các định dạng dữ liệu không xác định (lập trình meta)

0

ngôn ngữ gõ động giúp nhanh chóng tạo ra các khái niệm thuật toán nguyên mẫu mà không cần phải suy nghĩ về việc sử dụng loại biến nào (đây là điều cần thiết trong ngôn ngữ được gõ tĩnh e).


-15

Nhập tĩnh: Các ngôn ngữ như Java và Scala được gõ tĩnh.

Các biến phải được xác định và khởi tạo trước khi chúng được sử dụng trong mã.

cho người cũ int x; x = 10;

System.out.println (x);

Gõ động: Perl là một ngôn ngữ gõ động.

Các biến không cần phải được khởi tạo trước khi chúng được sử dụng trong mã.

y = 10; sử dụng biến này trong phần sau của mã


2
Vâng, câu trả lời này không hoàn toàn đúng. Trong cả hai ngôn ngữ, các biến phải được xác định trước khi chúng được sử dụng. Tuy nhiên, trong các ngôn ngữ được nhập động, bạn có thể chọn loại bỏ loại ngôn ngữ được sử dụng.
darshan

Có vẻ như bạn đang sử dụng sai cụm từ "biến", thay vào đó bạn nên nói "loại".
Tiểu vương quốc

Tôi cho rằng Perl được gõ tĩnh: Nó có 3 loại, vô hướng ( $), mảng ( @) và hàm băm ( %). Loại biến trong Perl được biết đến tại thời gian biên dịch và giữ nguyên cho phần còn lại của vòng đời biến.
CoffeeTableEspresso
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.