답변:
키워드 및 기호에 대한 Clojure 설명서 는 다음과 같습니다 .
키워드는 스스로 평가되는 기호 식별자입니다. 그들은 매우 빠른 평등 테스트를 제공합니다 ...
기호는 일반적으로 다른 것을 나타내는 데 사용되는 식별자입니다. 그들은 함수 매개 변수를 참조하고 바인딩, 클래스 이름 및 전역 변수를 참조하도록 프로그램 형태로 사용할 수 있습니다 ...
키워드는 일반적으로 가벼운 "일정한 문자열"로 사용됩니다 (예 : 해시 맵의 키 또는 멀티 메소드의 디스패치 값). 기호는 일반적으로 변수와 함수의 이름을 지정하는 데 사용되며 매크로 등을 제외하고 직접 개체로 조작하는 것은 일반적이지 않습니다. 그러나 키워드를 사용하는 모든 곳에서 기호를 사용하는 것을 막을 수있는 것은 없습니다 (항상 인용하는 것이 마음에 들지 않는 경우).
차이를 볼 수있는 가장 쉬운 방법은 읽을 수 Keyword.java
와 Symbol.java
Clojure의 소스에서. 몇 가지 명백한 구현 차이가 있습니다. 예를 들어 Clojure의 Symbol에는 메타 데이터가 있고 키워드에는 없습니다.
단일 콜론 구문 외에도 이중 콜론을 사용하여 네임 스페이스로 한정된 키워드를 만들 수 있습니다.
user> :foo
:foo
user> ::foo
:user/foo
일반적인 Lisp에는 Ruby 및 기타 언어와 마찬가지로 키워드가 있습니다. 물론 해당 언어에서는 약간 다릅니다. 공통 Lisp 키워드와 Clojure 키워드의 일부 차이점 :
Clojure의 키워드는 기호가 아닙니다.
user> (symbol? :foo)
false
구체적으로 규정하지 않은 키워드는 네임 스페이스에 속하지 않습니다.
user> (namespace :foo)
nil
user> (namespace ::foo)
"user"
( 볼만한 것들에 대한 아이디어를 주신 Rainer Joswig 에게 감사드립니다 .)
(eval (eval ':a))
대 (eval (eval ''a))
. 다른 장점이 있습니까? 현명한 성능, 그들은 동일합니까?
공통 Lisp 에는 키워드 기호가 있습니다.
키워드도 상징입니다.
(symbolp ':foo) -> T
키워드를 특별하게 만드는 이유 :
그렇지 않으면 키워드는 일반적인 기호입니다. 키워드는 함수의 이름을 지정하거나 속성 목록을 가질 수 있습니다.
기억하십시오 : 공통 Lisp 기호는 패키지에 속합니다. 이것은 다음과 같이 쓸 수 있습니다 :
키워드 기호의 경우 : foo, keyword : foo 및 keyword :: foo는 모두 동일한 기호입니다. 따라서 후자의 두 표기법은 일반적으로 사용되지 않습니다.
따라서 : foo는 심볼 이름 앞에 패키지 이름을 지정하지 않으면 기본적으로 KEYWORD 패키지를 의미한다고 가정하고 패키지 KEYWORD에 포함되도록 구문 분석됩니다.
키워드는 자체 평가되는 기호이므로 따로 인용 할 필요가 없습니다.
키워드는 전역 이며 기호는 다릅니다 .
이 예제는 JavaScript로 작성되었지만 요점을 파악하는 데 도움이되기를 바랍니다.
const foo = Symbol.for(":foo") // this will create a keyword
const foo2 = Symbol.for(":foo") // this will return the same keyword
const foo3 = Symbol(":foo") // this will create a new symbol
foo === foo2 // true
foo2 === foo3 // false
Symbol
함수를 사용하여 심볼을 구성 할 때 마다 고유 / 개인 심볼이 나타납니다. Symbol.for
함수 를 통해 기호를 요청하면 매번 같은 기호가 나타납니다.
(println :foo) ; Clojure
System.out.println(RT.keyword(null, "foo")) // Java
console.log(System.for(":foo")) // JavaScript
이것들은 모두 같습니다.
함수 인수 이름은 로컬입니다. 즉 키워드가 아닙니다.
(def foo (fn [x] (println x))) ; x is a symbol
(def bar (fn [x] (println x))) ; not the same x (different symbol)