Kiểu hệ thống: danh nghĩa so với cấu trúc, rõ ràng so với ẩn


24

Tôi hơi bối rối về sự khác biệt giữa các hệ thống loại danh nghĩa và cấu trúc. Ai đó có thể vui lòng giải thích chúng khác nhau như thế nào?

Từ những gì tôi hiểu:

  • Danh nghĩa: Khả năng tương thích loại dựa trên tên loại.
  • Cấu trúc: Khả năng tương thích kiểu dựa trên cấu trúc kiểu, ví dụ trong C nếu 2 biến là kiểu cấu trúc có tên khác nhau nhưng có cùng cấu trúc thì kiểu của chúng tương thích.

Bây giờ về rõ ràng và ẩn: tại sao nó khác với gõ tĩnh và động? Trong kiểu gõ tĩnh, các kiểu sẽ rõ ràng trong khi gõ động, các kiểu được ẩn. Tôi có đúng không

Câu trả lời:


29

Trong một hệ thống được gõ động, các giá trị có các kiểu trong thời gian chạy nhưng các biến và hàm thì không. Trong một hệ thống gõ tĩnh, các biến và hàm có các loại được biết và kiểm tra tại thời gian biên dịch. Ví dụ, trong Python xcó thể là bất cứ điều gì ; trong thời gian chạy, nếu đó là 1một số và nếu có "foo", đó là một chuỗi. Bạn sẽ chỉ biết loại nào xlà trong thời gian chạy, và nó có thể khác nhau mỗi khi bạn chạy chương trình. Trong một ngôn ngữ như Java, bạn sẽ viết int xnếu xlà một số và bạn sẽ biết vào thời gian biên dịch xluôn phải là một số int.

Cả hai loại "ngầm" và "ngầm" đều đề cập đến các hệ thống kiểu tĩnh . Đặc điểm xác định của một hệ thống tĩnh là các loại được biết tại thời điểm biên dịch, nhưng không nhất thiết là chúng phải được viết ra. Trong Java, các kiểu là rõ ràng - bạn phải viết chúng ra. Vì vậy, trong Java, một phương thức có thể trông giống như:

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

Các loại đều được biết đến tại thời gian biên dịch (tĩnh) viết ra (rõ ràng). Tuy nhiên, cũng có những ngôn ngữ không bắt buộc bạn phải viết ra. Họ có thể suy ra loại chức năng từ cơ thể của nó và cách nó được sử dụng. Một ví dụ sẽ là OCaml, nơi bạn có thể viết một cái gì đó như:

let foo x = x + 1

Vì bạn đã sử dụng +, OCaml có thể tự mình hiểu ra rằng đó xphải là inttất cả. Vì vậy, loại foo( foo : int -> int) được biết đến tại thời điểm biên dịch, giống như ví dụ Java. Nó hoàn toàn tĩnh. Tuy nhiên, vì trình biên dịch có thể tự tìm ra các loại phải là gì, bạn không cần phải tự viết chúng ra: chúng ẩn.

Tóm lại: liệu một hệ thống loại là rõ ràng hay ẩn là một thuộc tính của các hệ thống tĩnh . Đó là một câu hỏi hoàn toàn khác với việc một hệ thống kiểu là động hay tĩnh.

Thông thường, bạn có các hệ thống loại đôi khi rõ ràng và đôi khi ẩn.

Ví dụ: tôi tin rằng C # cho phép bạn suy luận các loại bằng cách sử dụng vartừ khóa. Vì vậy, thay vì viết int x = 10, bạn có thể viết var x = 10và trình biên dịch chỉ ra rằng đó xphải là một int. C ++ làm một cái gì đó tương tự với auto. Các hệ thống này thường rõ ràng nhưng có một số suy luận.

Trên flipside, có những hệ thống thường ẩn nhưng đôi khi buộc bạn phải viết ra một chữ ký loại. Haskell là một ví dụ tuyệt vời. Hầu hết thời gian, Haskell có thể suy ra các loại cho bạn. Tuy nhiên, đôi khi bạn có thể viết mã không rõ ràng show . read, trong đó Haskell không thể tự mình tìm ra các loại. Trong trường hợp này, bạn sẽ buộc phải chỉ định rõ ràng loại showhoặc read. Ngoài ra, một số tính năng nâng cao hơn của hệ thống loại (như đa hình hạng n) làm cho suy luận không thể giải quyết được - nghĩa là, nó không được bảo đảm để dừng lại. Điều này có nghĩa là mã sử dụng tính năng này thường cần chữ ký loại rõ ràng.


2
Trên thực tế, có một số ngôn ngữ với những gì bạn có thể gọi là gõ động rõ ràng . Thông thường, các ngôn ngữ đó cho phép bạn chú thích các biểu thức với các loại và sau đó các loại đó sẽ được kiểm tra trong thời gian chạy so với loại thời gian chạy của biểu thức.
Jörg W Mittag

chỉ là một độ chính xác: loại hệ thống không ẩn hoặc rõ ràng. Đây chỉ là về suy luận kiểu, về cơ bản là cách tạo ra các thuật ngữ hợp lệ trong một hệ thống loại từ một cú pháp khác nhau (đôi khi không xác định).
Eduardo Pareja Tobes

Câu trả lời tốt, nhưng điều này không giải quyết được danh nghĩa so với gõ cấu trúc. Một chỉnh sửa sẽ là tuyệt vời.
bữa ăn trưa317

7
  • tĩnh so với động mô tả khi các loại được kiểm tra (nhiều hơn hoặc ít hơn tại thời gian biên dịch hoặc tại thời gian thực hiện)

  • danh nghĩa so với cấu trúc mô tả khi hai loại được coi là giống nhau.

(Và có các biến thể, được biết đến nhiều nhất là biến thể của kiểu gõ cấu trúc chỉ xem xét những gì được sử dụng thay vì toàn bộ kiểu được gọi là gõ vịt).

Bốn kết hợp (danh nghĩa tĩnh, cấu trúc tĩnh, danh nghĩa động, cấu trúc động) là có thể, và các ngôn ngữ thường không hoàn toàn trong một lớp nhưng có các khía cạnh trong các lớp khác.

Ví dụ, các hệ thống loại của C ++ là tĩnh, chủ yếu là danh nghĩa nhưng có cấu trúc khi bạn xem xét các mẫu (và bạn có thể coi một phần của các vấn đề xung quanh các khái niệm trong C ++ là xung đột giữa những người muốn chuyển từ gõ vịt sang dạng gõ cấu trúc đầy đủ và những người muốn đi đánh máy danh nghĩa). Và việc sử dụng các lớp và kế thừa cho phép sử dụng một kiểu gõ động và danh nghĩa trong một số trường hợp.

Ngôn ngữ mà một hệ thống kiểu động thường sử dụng kiểu cấu trúc, nhưng CLOS là các khía cạnh danh nghĩa.


1

Cấu trúc: Khả năng tương thích kiểu dựa trên cấu trúc kiểu, ví dụ trong C nếu 2 biến là kiểu cấu trúc có tên khác nhau nhưng có cùng cấu trúc thì kiểu của chúng tương thích.

Đây thường không phải là trường hợp. Gõ cấu trúc có nghĩa Blà một kiểu con Anếu nó có thể đáp ứng Agiao diện của nó. Điều này thường có nghĩa là có các thành viên có cùng tên; không chỉ là cấu trúc tương tự trong bộ nhớ.

Điều này khác với kiểu gõ chỉ định yêu cầu các loại siêu được chỉ định khi khai báo.


1

Giải thích tốt nhất mà tôi đã thấy về sự khác biệt giữa (thực sự là sự sụt giảm) của các hệ thống kiểu động và tĩnh là trong bài đăng trên blog này của Bob Harper:

Điểm chính của nó có thể được tóm tắt là:

  • ngôn ngữ động là những ngôn ngữ tĩnh chỉ có một loại

1
Liên kết có thể xấu đi; bạn nên trích dẫn các bit có liên quan nhất của bài viết để chúng được bảo tồn cho hậu thế ngay cả khi blog bị lỗi.
Doval

2
Chắc chắn rồi. Tôi nghĩ rằng trong trường hợp này, câu tôi đã thêm là đủ :)
Eduardo Pareja Tobes
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.