2009-10-06 26 views
111

Tôi có một kiến ​​thức đi qua của Lisps khác (đặc biệt là Đề án) từ cách trở lại. Gần đây tôi đã đọc về Clojure. Tôi thấy rằng nó có cả "ký hiệu" và "từ khóa". Biểu tượng tôi quen thuộc, nhưng không phải với từ khóa.Tại sao Clojure có "từ khóa" ngoài "biểu tượng"?

Các từ khóa khác có từ khóa không? Các từ khóa khác với các ký hiệu khác với các ký hiệu khác nhau như thế nào (ví dụ: dấu hai chấm)?

+0

Xem thêm: [trong Clojure, tại sao có Chuỗi, Từ khóa và Ký hiệu?] (Http://stackoverflow.com/q/11655080/405550) – Zaz

Trả lời

119

Đây là Clojure documentation cho Từ khóa và Ký hiệu.

Từ khóa là số nhận dạng tượng trưng tự đánh giá. Chúng cung cấp các bài kiểm tra bình đẳng rất nhanh ...

Ký hiệu là số nhận dạng thường được sử dụng để chỉ một thứ khác. Chúng có thể được sử dụng trong các biểu mẫu chương trình để tham chiếu đến các tham số chức năng, cho phép các ràng buộc, tên lớp và vars toàn cầu ...

Từ khóa thường được sử dụng như là "chuỗi không đổi" trọng lượng nhẹ, ví dụ: cho các khóa của bản đồ băm hoặc giá trị công văn của một đa phương thức. Các ký hiệu thường được sử dụng để đặt tên biến và hàm và ít phổ biến hơn để thao tác chúng như là các đối tượng trực tiếp ngoại trừ trong các macro và như vậy. Nhưng không có gì ngăn cản bạn sử dụng một biểu tượng ở khắp mọi nơi bạn sử dụng một từ khóa (nếu bạn không nhớ trích dẫn chúng tất cả thời gian).

Cách dễ nhất để thấy sự khác biệt là đọc Keyword.javaSymbol.java trong nguồn Clojure. Có một vài khác biệt thực hiện rõ ràng. Ví dụ: Biểu tượng trong Clojure có thể có siêu dữ liệu và từ khóa không thể.

Ngoài cú pháp một dấu hai chấm, bạn có thể sử dụng dấu hai chấm để tạo từ khóa đủ điều kiện không gian tên.

user> :foo 
:foo 
user> ::foo 
:user/foo 

Lisp thường có từ khóa, cũng như Ruby và các ngôn ngữ khác. Họ là hơi khác nhau trong những ngôn ngữ của khóa học. Một số khác biệt giữa từ khóa thường gặp Lisp và từ khóa Clojure:

  1. Từ khóa trong Clojure không phải là Ký hiệu.

    user> (symbol? :foo) 
    false 
    
  2. Từ khóa không thuộc về bất kỳ không gian tên trừ khi bạn đủ điều kiện cho họ: (. Cảm ơn Rainer Joswig đã cho tôi ý tưởng về điều cần xem xét)

    user> (namespace :foo) 
    nil 
    user> (namespace ::foo) 
    "user" 
    

+9

Điều này giải thích _what_ sự khác biệt là gì, nhưng không phải lý do tại sao hai cấu trúc khác nhau là cần thiết. Clojure không thể tạo ra một cái gì đó với sự kết hợp của các khả năng của cả hai từ khóa và biểu tượng? – mtnygard

+20

Từ khóa có trọng lượng nhẹ và có cú pháp thuận tiện, tôi nghĩ đó là tất cả về nó. Ngôn ngữ sẽ hoạt động tốt mà không có chúng nhưng chúng rất tốt và chúng được sử dụng rộng rãi. Bạn không thể kết hợp khả năng của mình vì Từ khóa luôn tự đánh giá (nghĩa là bạn không thể sử dụng chúng làm tên biến hoặc hàm) và Biểu tượng nói chung không thể luôn tự đánh giá. –

+1

Dường như các từ khóa hữu ích hơn như các khóa trong hashmaps vv vì chúng không thay đổi khi đã đánh giá: '(eval (eval ': a))' vs '(eval (eval' 'a))'. Có lợi thế nào khác không? Hiệu suất khôn ngoan, chúng giống hệt nhau? – kristianlm

5

Từ khóa là các biểu tượng tự đánh giá, vì vậy bạn không phải nhớ trích dẫn chúng.

+5

Có phải không? Nhập: thay vì 'không có vẻ giống như một chiến thắng lớn, đặc biệt là kể từ: là một phím bổ sung trên hầu hết bàn phím. –

+8

Vâng, nó còn hơn cả nhân vật. Từ khóa vẫn giữ các từ khóa sau khi đánh giá, trong khi các ký hiệu được đánh giá cho bất kỳ từ khóa nào mà chúng liên kết. Nó giống như một sự khác biệt ngữ nghĩa, bởi vì chúng thường được sử dụng cho các mục đích khác nhau. –

+12

Từ khóa không phải là biểu tượng trong Clojure –

26

Common Lisp có các ký hiệu từ khóa.

Từ khóa cũng là biểu tượng.

(symbolp ':foo) -> T 

Điều gì làm cho các từ khóa đặc biệt:

  • : foo được phân tách bởi người đọc Common Lisp như từ khóa biểu tượng :: foo
  • từ khóa đánh giá cho riêng mình:: foo ->: foo
  • gói nhà của các biểu tượng từ khóa là gói KEYWORD: từ khóa: foo ->: foo
  • từ khóa được xuất từ ​​gói KEYWORD
  • từ khóa là hằng số, không được phép chỉ định giá trị khác nhau

Nếu không, từ khóa là ký hiệu thông thường. Vì vậy, từ khóa có thể đặt tên cho các hàm hoặc có danh sách thuộc tính.

Hãy nhớ: trong biểu tượng Lisp chung thuộc về gói. Điều này có thể được viết như sau:

  • foo, khi biểu tượng có thể truy cập trong gói hiện
  • foo: quầy bar, khi FOO biểu tượng được xuất khẩu từ BAR gói
  • foo :: bar, khi biểu tượng FOO nằm trong gói BAR

Đối với các ký hiệu từ khóa có nghĩa là: foo, keyword: foo và keyword :: foo đều có cùng biểu tượng. Vì vậy, hai ký hiệu sau thường không được sử dụng.

Vì vậy: foo chỉ được phân tích cú pháp trong gói KEYWORD, giả định rằng không đặt tên gói trước tên biểu tượng có nghĩa là theo mặc định gói KEYWORD.

2

: từ khóa cũng được xử lý đặc biệt bởi nhiều bộ sưu tập, cho phép một số cú pháp thực sự thuận tiện.

(:user-id (get-users-map)) 

cũng giống như

((get-users-map) :user-id) 

này làm cho mọi thứ chỉ là một chút flexable hơn

+19

Điều này cũng đúng đối với các ký hiệu, ('a {' a 1 'b 2}) => 1 và ({' a 1 'b 2}' b) => 2. – Jonas

3

Đối với từ khoá, giá trị băm được tính toán và lưu trữ khi từ khóa là đầu tiên được xây dựng. Khi tra cứu từ khóa dưới dạng khóa băm, nó chỉ đơn giản là trả về giá trị băm được tính trước. Đối với chuỗi và ký hiệu, hàm băm được tính toán lại trên mọi lần tra cứu.

Lý do tại sao cùng một từ khóa được đặt tên luôn giống nhau, chúng chứa giá trị băm của riêng chúng. Khi tìm kiếm trong bản đồ và tập hợp được thực hiện từ các khóa băm, điều này mang lại hiệu quả tìm kiếm tốt hơn trong trường hợp có nhiều tìm kiếm, không phải trong chính tìm kiếm.

Các vấn đề liên quan