Khi nào một tính năng được coi là một công dân hạng nhất của Pháp trong ngôn ngữ / nền tảng lập trình?


61

Tôi đã thấy nhiều lần tuyên bố như- "Xin hãy biến tính năng này thành một công dân hạng nhất bằng ngôn ngữ / nền tảng". Ví dụ, người ta nói về enums trong C # /. Net. Vậy, khi nào một tính năng được coi là "công dân hạng nhất" trong ngôn ngữ / nền tảng lập trình?

Câu trả lời:


40

Định nghĩa

Một đối tượng là hạng nhất khi nó:

  • có thể được lưu trữ trong các biến và cấu trúc dữ liệu
  • có thể được truyền dưới dạng tham số cho chương trình con
  • có thể được trả về như là kết quả của chương trình con
  • có thể được xây dựng trong thời gian chạy
  • có bản sắc nội tại (độc lập với bất kỳ tên nào)

Thuật ngữ "đối tượng" được sử dụng một cách lỏng lẻo ở đây, không nhất thiết phải nói đến các đối tượng trong lập trình hướng đối tượng. Các kiểu dữ liệu vô hướng đơn giản nhất, chẳng hạn như số nguyên và số dấu phẩy động, gần như luôn luôn là hạng nhất.

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


1
Vì vậy, điều gì làm cho enums đối tượng lớp thứ hai trong .net / C #?
Gul Sơn

7
@Gulshan - bạn có thể tranh luận về việc thiếu bản sắc nội tại - C # enums về cơ bản chỉ là đường cú pháp (tức là "tên đã cho") cho một giá trị nguyên. So sánh với Java, trong đó enum là các đối tượng theo cách riêng của chúng.
mikera

@mikera, trong .NET enums là các giá trị theo cách riêng của họ. Java không có bất kỳ giá trị nào, chỉ có các đối tượng, đó là điểm khác biệt duy nhất.
SK-logic

@mikera: Mặc dù điều đó ngăn các enum của Java có một số thuộc tính đẹp như có thể biểu diễn các trường bit với chúng. Mặc dù việc triển khai của chúng có lẽ là hạng nhất, hầu hết các API của chúng vẫn có nhiều hằng số nguyên (hoặc chuỗi) và nhiều cách sử dụng chúng không thể dễ dàng được thay thế bằng enum.
Joey

Tôi không nghĩ enums có thể được xây dựng trong thời gian chạy trong .Net, phải không? Tôi nghĩ rằng họ luôn luôn là hằng số.
ngày

33

Khái niệm "công dân hạng nhất" hay "yếu tố hạng nhất" trong ngôn ngữ lập trình được giới thiệu bởi nhà khoa học máy tính người Anh Christopher Strachey vào những năm 1960 trong bối cảnh các chức năng hạng nhất. Công thức nổi tiếng nhất của nguyên tắc này có lẽ là trong Cấu trúc và diễn giải các chương trình máy tính của Gerald Jay Sussman và Harry Abelson:

  • Chúng có thể được đặt tên theo các biến.
  • Họ có thể được thông qua như là đối số để làm thủ tục.
  • Họ có thể được trả lại như là kết quả của các thủ tục.
  • Chúng có thể được bao gồm trong cấu trúc dữ liệu.

Về cơ bản, điều đó có nghĩa là bạn có thể làm với phần tử ngôn ngữ lập trình này mọi thứ bạn có thể làm với tất cả các phần tử khác trong ngôn ngữ lập trình.

Đó là tất cả về "quyền bình đẳng": bạn có thể thực hiện tất cả các điều trên, với, giả sử, số nguyên, vậy tại sao mọi thứ khác phải khác?

Định nghĩa ở trên là một chút hạn chế theo nghĩa là nó chỉ thực sự nói về khía cạnh của hạng nhất có liên quan đến việc là đối tượng của chương trình. Một định nghĩa chung hơn sẽ là một thứ là hạng nhất nếu bạn có thể làm mọi thứ với nó, bạn cũng có thể làm với những thứ khác cùng loại.

Ví dụ, các toán tử Java và các phương thức Java có cùng loại. Bạn có thể định nghĩa các phương thức mới, bạn có thể (phần nào) tự do chọn tên các phương thức của riêng bạn, bạn có thể ghi đè các phương thức, bạn có thể quá tải các phương thức. James Gosling cũng có thể làm tất cả điều đó với các nhà khai thác, nhưng bạn và tôi không thể. Ý tôi là, trái với niềm tin phổ biến, Java làm nhà điều hành hỗ trợ quá tải: ví dụ, các +nhà khai thác quá tải cho byte, short, int, long, float, doubleString, và IIRC trong Java 7 cũng cho BigIntegerBigDecimal(và có thể là một cặp vợ chồng tôi quên), nó chỉ là bạnkhông có bất kỳ ảnh hưởng nào đối với nó. Điều đó rõ ràng làm cho các nhà khai thác hạng hai theo định nghĩa thứ hai này. Lưu ý rằng các phương thức vẫn không có đối tượng hạng nhất theo định nghĩa đầu tiên, mặc dù. (Điều đó có làm cho các nhà khai thác hạng ba không?)


6

Thông thường, điều này đề cập đến một cấu trúc có thể vượt qua như một tham số, có thể được định nghĩa là một kiểu trả về từ một hàm hoặc có thể được gán một giá trị. Thông thường bạn cần có khả năng xây dựng chúng trong thời gian chạy. Ví dụ, một thể hiện của một lớp sẽ là một công dân hạng nhất trong c ++ hoặc java, nhưng một hàm trong C thì không.


Điều gì làm cho một lớp là một công dân hạng nhất trong c ++?
Bjarke Freund-Hansen

2
@bjarkef: Âm thanh như thế đã được trả lời bằng cách khớp với mô tả được cung cấp trong các câu trước.
doppelgreener

@Jonathan: Vâng, xin lỗi, tôi đã đọc sai "xây dựng chúng khi chạy". Có, bạn có thể xây dựng một thể hiện của một lớp trong thời gian chạy (một đối tượng), nhưng không phải chính lớp đó. Đó là điều làm tôi bối rối.
Bjarke Freund-Hansen

1
Đi qua tham số vẫn chưa đủ. Trong C / C ++ tôi vẫn sẽ coi các chức năng là công dân hạng hai. Chúng có thể được truyền dưới dạng tham số, được trả về dưới dạng kết quả được đặt bên trong các đối tượng khác. Nhưng chúng không thể được thao tác nếu không có sự trợ giúp của các cấu trúc khác (như std :: bind là bắt buộc để liên kết các tham số với hàm).
Martin York

@Martin Tôi chưa bao giờ nói rằng các chức năng là công dân hạng nhất trong C / C ++.
Pemdas

1

Tôi muốn nói một tính năng là một công dân hạng nhất nếu nó được thực hiện chỉ bằng ngôn ngữ.
tức là nó không yêu cầu nhiều tính năng ngôn ngữ hoặc thư viện chuẩn để thực hiện tính năng đó.

Thí dụ:

Trong C / C ++, tôi không coi các chức năng là một công dân hạng nhất (những người khác có thể).
Điều này là do có nhiều cách để thao tác các chức năng được hỗ trợ trực tiếp bởi ngôn ngữ nhưng yêu cầu sử dụng các tính năng ngôn ngữ khác. Các tham số ràng buộc cho một chức năng không được hỗ trợ trực tiếp và bạn phải xây dựng một functor để thực hiện tính năng này.


1
Điều đó sẽ không làm cho các hàm bị ràng buộc (hoặc "đóng cửa") không phải là hạng nhất, trong khi chính các hàm là? Làm thế nào để hỗ trợ của 0x cho các yếu tố đóng cửa trong phân tích của bạn?
Fred Nurk

@Fred Nurk: Tất cả phụ thuộc vào ngôn ngữ. Trong một số ngôn ngữ đóng cửa là hệ thống hạng nhất. Ở người khác thì không. Tôi chưa đủ quen thuộc với C ++ 0x để đưa ra nhận xét rõ ràng.
Martin York

Giả sử ngôn ngữ là C hoặc C ++ (nhưng không phải 0x), như trong câu trả lời của bạn. Không phải định nghĩa của bạn về "hạng nhất" sẽ khiến các hàm bị ràng buộc (hoặc "đóng cửa") không phải là hạng nhất, trong khi bản thân các hàm là?
Fred Nurk

@Fred Nurk: Nếu bạn giới hạn điều duy nhất bạn có thể làm với một chức năng là làm cho chúng đóng lại, thì chắc chắn. Nhưng với tôi điều đó giống như nói rằng nếu nền tảng của bạn chỉ hỗ trợ số nguyên bằng cách nhập thư viện. Sau đó, số nguyên là công dân hạng nhất nhưng việc thêm số nguyên không được xem xét. Theo quan điểm của tôi, đóng cửa là một hoạt động có thể được thực hiện trên một hàm có hiệu quả trả về một hàm mới (nhưng nó phụ thuộc vào cách bạn xác định nó). Nhưng đóng cửa và ràng buộc chỉ là hai hoạt động có bao nhiêu hoạt động khác mà chúng tôi loại trừ khỏi cuộc thảo luận (tôi không chắc đó là một câu hỏi).
Martin York

@Martin: Tôi không được giải thích rõ ràng về bản thân. Cho rằng "một tính năng là một công dân hạng nhất nếu nó được triển khai chỉ bằng ngôn ngữ", thì các chức năng trong cả C và C ++ chỉ được thực hiện bởi ngôn ngữ và do đó sẽ là hạng nhất. Các hàm giới hạn (cũng có thể được gọi là "bao đóng") là những gì bạn đang nói về các tham số ràng buộc, v.v., nhưng đó là một tính năng khác.
Fred Nurk

-1

Để thêm một ví dụ cho các câu trả lời đã được cung cấp:

Trong WCF / C #, bạn hiện phải đánh dấu một đối tượng lớp bằng thuộc tính hợp đồng dịch vụ để nó hoạt động như một dịch vụ. Không có những thứ như:

public **service** MyService (in relation public **class** MyClass). 

Một lớp là một công dân hạng nhất trong c #, nơi không có dịch vụ.

Hi vọng điêu nay co ich

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.