Clojure에 명명 된 인수가 있습니까? 그렇다면 작은 예를 들어 주시겠습니까?
답변:
Clojure 1.2에서는 rest
맵을 해체하는 것처럼 인수를 해체 할 수 있습니다. 즉, 명명 된 비 위치 키워드 인수를 수행 할 수 있습니다. 다음은 예입니다.
user> (defn blah [& {:keys [key1 key2 key3]}] (str key1 key2 key3))
#'user/blah
user> (blah :key1 "Hai" :key2 " there" :key3 10)
"Hai there10"
user> (blah :key1 "Hai" :key2 " there")
"Hai there"
user> (defn blah [& {:keys [key1 key2 key3] :as everything}] everything)
#'user/blah
user> (blah :key1 "Hai" :key2 " there")
{:key2 " there", :key1 "Hai"}
아무것도 위의 그림과 같이 Clojure의 맵을 destructuring 동안 당신이 할 수있는 함수의 인수 목록에서 수행 할 수 있습니다. : or를 사용하여 다음과 같은 인수의 기본값을 정의하는 것을 포함합니다.
user> (defn blah [& {:keys [key1 key2 key3] :or {key3 10}}] (str key1 key2 key3))
#'user/blah
user> (blah :key1 "Hai" :key2 " there")
"Hai there10"
그러나 이것은 Clojure 1.2에 있습니다. 또는 이전 버전에서는 다음과 같이 동일한 작업을 시뮬레이션 할 수 있습니다.
user> (defn blah [& rest] (let [{:keys [key1 key2 key3] :or {key3 10}} (apply hash-map rest)] (str key1 key2 key3)))
#'user/blah
user> (blah :key1 "Hai" :key2 " there")
"Hai there10"
일반적으로 동일한 방식으로 작동합니다.
또한 키워드 인수 앞에 오는 위치 인수를 가질 수도 있습니다.
user> (defn blah [x y & {:keys [key1 key2 key3] :or {key3 10}}] (str x y key1 key2 key3))
#'user/blah
user> (blah "x" "Y" :key1 "Hai" :key2 " there")
"xYHai there10"
이는 선택 사항이 아니므로 제공해야합니다.
rest
Clojure 컬렉션처럼 인수를 실제로 분해 할 수 있습니다 .
user> (defn blah [& [one two & more]] (str one two "and the rest: " more))
#'user/blah
user> (blah 1 2 "ressssssst")
"12and the rest: (\"ressssssst\")"
Clojure 1.1에서도 이런 일을 할 수 있습니다. 그러나 키워드 인수에 대한 맵 스타일 구조 해제는 1.2에서만 제공되었습니다.
Raynes의 탁월한 답변 외에도 clojure-contrib 에는 삶을 더 쉽게 만들어주는 매크로 가 있습니다 .
user => ( '[clojure.contrib.def : only [defnk]] 사용) 무 사용자 => (defnk foo [ab : c 8 : d 9] [abcd]) # 'user / foo 사용자 => (foo 1 2) [1 2 8 9] 사용자 => (foo 1 2 3) java.lang.IllegalArgumentException : 키에 제공된 값 없음 : 3 (NO_SOURCE_FILE : 0) 사용자 => (foo 1 2 : c 3) [1 2 3 9]
Clojure 버전 1.8에서 키워드 지원은 여전히 약간 meh .
다음과 같이 키워드 인수를 지정할 수 있습니다.
(defn myfn1
"Specifying keyword arguments without default values"
[& {:keys [arg1 arg2]}]
(list arg1 arg2))
호출의 예 :
(myfn1 :arg1 23 :arg2 45) --> evaluates to (23 45)
(myfn1 :arg1 22) --> evaluates to (22 nil)
이러한 키워드 인수에 대한 기본값을 지정하려면 다음을 수행하십시오.
(defn myfn2
"Another version, this time with default values specified"
[& {:keys [arg1 arg2] :or {arg1 45 arg2 55}}]
(list arg1 arg2))
이것은 두 번째 경우에 예상되는 일을 수행합니다.
(myfn2 :arg1 22) --> evaluates to (22 55)
각 언어의 각 부분에는 장단점이 있지만 비교를 위해 Common Lisp에서 동일한 작업을 수행하는 방법은 다음과 같습니다.
(defun myfn3
(&key arg1 arg2)
"Look Ma, keyword args!"
(list arg1 arg2))
(defun myfn4
(&key (arg1 45) (arg2 55))
"Once again, with default values"
(list arg1 arg2))
명명 된 매개 변수를 의미 합니까? 직접 사용할 수는 없지만 원하는 경우이 벡터 접근 방식을 사용할 수 있으므로 원하는 것을 얻을 수 있습니다.
RosettaCode 에는 비 구조화를 사용하여이를 수행하는 방법에 대한 자세한 설명이 있습니다.