Clojure는 gen-class, reify, proxy 및 deftype 및 defrecord를 사용하여 새로운 클래스와 유사한 데이터 유형을 정의합니다. 구문의 단순성을 중요시하고 불필요한 복잡성을 싫어하는 언어의 경우 일탈처럼 보입니다. 누군가 그 이유를 설명 할 수 있습니까? Common Lisp 스타일의 defclass가 충분할까요?
답변:
다음은 세 가지 요소가 혼합 된 것입니다.
따라서 먼저 이것이 무엇을하는지 고려해 봅시다. deftype 및 gen-class 는 둘 다 사전 컴파일을 위해 명명 된 클래스를 정의한다는 점에서 유사합니다. Gen-class가 먼저 왔고 clojure 1.2에서 deftype이 그 뒤를이었습니다. Deftype이 선호되고 성능 특성이 더 좋지만 더 제한적입니다. deftype 클래스는 인터페이스를 준수 할 수 있지만 다른 클래스에서 상속 할 수 없습니다.
Reify 와 프록시 는 모두 런타임에 익명 클래스의 인스턴스를 동적으로 만드는 데 사용됩니다. 프록시가 먼저 왔고 reify는 clojure 1.2에서 deftype 및 defrecord와 함께 제공되었습니다. Reify는 의미가 너무 제한적이지 않은 deftype과 마찬가지로 선호됩니다.
그것은 왜 deftype과 defrecord가 동시에 나타나고 비슷한 역할을하는지에 대한 의문을 남깁니다. 대부분의 목적을 위해 우리는 defrecord를 사용하고 싶을 것입니다. 그것은 우리가 알고 사랑하는 모든 클로저의 장점을 가지고 있습니다. Deftype은 다른 데이터 구조의 구현을위한 저수준 빌딩 블록으로 사용하기위한 것입니다. 일반 클로저 인터페이스는 포함하지 않지만 변경 가능한 필드 옵션이 있습니다 (기본값은 아님).
자세한 내용은 다음을 확인하세요.
proxy
런타임에 메서드를 수정할 수 있기 때문에 때때로 선호됩니다. (예 : The Joy of Clojure , 2nd ed.는 이것이 웹 핸들러에서 콜백을 수정하는 데 유용 할 수 있다고 제안합니다.)
짧은 대답은 모두 다르고 유용한 목적을 가지고 있다는 것입니다. 복잡성은 기본 JVM의 다양한 기능과 효과적으로 상호 운용되어야하기 때문입니다.
Java interop이 필요하지 않은 경우 99 %의 시간 동안 defrecord 또는 간단한 Clojure 맵을 사용하는 것이 가장 좋습니다.
요구 사항이 더 복잡한 경우 다음 순서도는 다른 옵션 중 하나를 선택하는 이유를 설명하는 훌륭한 도구입니다.
http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/