2013-08-26 4 views
7

내가 Clojure의에 안돼서과 같이 호출 할 수있는 기능을 정의하는 방법이 있는지 궁금 해서요 :가변 인자 함수는

입니다
(strange-adder 1 2 3 :strange true) 

, 함수하면받을 수 있습니다 int 수와 키워드 인수의 가변 수.

은 내가 키워드 인수를 이런 식으로 함수를 정의 할 수 있다는 사실을 알고 :

(defn strange-adder 
    [a b c & {:keys [strange]}] 
    (println strange) 
    (+ a b c)) 

하지만 지금 내 기능은 INT의 고정 번호를받을 수 있습니다.

두 가지 스타일을 동시에 사용할 수 있습니까?

답변

8

불행히도, 아니요.

구조체 조작자는 인수 목록에서 이후의 모든 것을 사용하므로 하나의 형식으로 두 개의 다른 가변 arity destructuring 그룹을 처리 할 수 ​​없습니다.

하나의 옵션은 여러 가지 기능으로 기능을 나누는 것입니다. 비록 당신이 그것을 배열 할 수있는 경우에만이 중 하나만이 variadic (&을 사용)입니다. 보다 보편적이고 덜 편리한 해결책은 전체 인수 목록을 하나의 가변 형식으로 취급하고 수동으로 시작 부분에서 번호를 선택하는 것입니다.

user> (defn strange-adder 
     [& args] 
     (let [nums (take-while number? args) 
       opts (apply hash-map (drop-while number? args)) 
       strange (:strange opts)] 
      (println strange) 
       (apply + nums))) 
#'user/strange-adder 
user> (strange-adder 1 2 3 4 :strange 4) 
4 
10 
1

가 내가 알고있는 공식적인 지원은 없지만, 이런 일이 행할 수 있어야한다 :

(defn strange-adder 
    [& args] 
    (if (#{:strange} (-> args butlast last)) 
    (do (println (last args)) 
     (apply + (drop-last 2 args))) 
    (apply + args))) 

이 일반화 될 수 있는지 모르겠어요 (키워드를 확인하는 방법 확장 임의의 수의 최종 인수로?). 하나의 옵션은 해시 맵의 모든 옵션을 최종 인수로두고 마지막 인수가 hashmap인지 확인하는 것입니다 (하지만 해시 맵일 수있는 임의의 인수를 기대하는 일부 함수에서는 작동하지 않습니다).

4
는 인수 목록의 꼬리에 가변 부분을 이동하고지도로 옵션을 전달

:

(defn strange-adder [{:keys [strange]} & nums] 
    (println strange) 
    (apply + nums)) 

(strange-adder {:strange true} 1 2 3 4 5)