답변:
서명이 서로 다른 경우 함수는 여러 서명을 가질 수 있습니다. 이를 사용하여 기본값을 제공 할 수 있습니다.
(defn string->integer
([s] (string->integer s 10))
([s base] (Integer/parseInt s base)))
가정 false
하고 nil
둘 다 값이 아닌 것으로 간주 하면을 (if (nil? base) 10 base)
단축하거나을 (if base base 10)
더 단축 할 수 있습니다 (or base 10)
.
recur
동일한 인수에 대응에서만 작동합니다. 예를 들어, 위와 같이 되풀이를 시도한 경우java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:
(string->integer s 10)
입니까?
rest
Clojure 1.2 [ ref ] 이후로 인수를 맵으로 재구성 할 수도 있습니다 . 이를 통해 함수 인수의 이름을 지정하고 기본값을 제공 할 수 있습니다.
(defn string->integer [s & {:keys [base] :or {base 10}}]
(Integer/parseInt s base))
이제 전화 할 수 있습니다
(string->integer "11")
=> 11
또는
(string->integer "11" :base 8)
=> 9
https://github.com/Raynes/clavatar/blob/master/src/clavatar/core.clj (예 :) 에서이를 확인할 수 있습니다.
이 솔루션은 원래 솔루션 의 정신에 더 가깝지만 조금 더 깨끗합니다.
(defn string->integer [str & [base]]
(Integer/parseInt str (or base 10)))
유사한 패턴 편리한 사용을 할 수 있습니다 or
와 함께let
(defn string->integer [str & [base]]
(let [base (or base 10)]
(Integer/parseInt str base)))
이 경우 더 자세한 정보를 제공하지만 다른 입력 값에 따라 기본값 을 설정하려는 경우 유용 할 수 있습니다 . 예를 들어 다음 기능을 고려하십시오.
(defn exemplar [a & [b c]]
(let [b (or b 5)
c (or c (* 7 b))]
;; or whatever yer actual code might be...
(println a b c)))
(exemplar 3) => 3 5 35
이 접근법은 M. Gilliar의 솔루션에서 와 같이 명명 된 인수 로 작업하도록 쉽게 확장 할 수 있습니다 .
(defn exemplar [a & {:keys [b c]}]
(let [b (or b 5)
c (or c (* 7 b))]
(println a b c)))
또는 더 많은 융합을 사용하십시오.
(defn exemplar [a & {:keys [b c] :or {b 5}}]
(let [c (or c (* 7 b))]
(println a b c)))
or
or
다른 :or
이후 or
의 차이를 알고하지 않습니다 nil
및 false
.
고려해야 할 또 다른 접근법이 있습니다 : 부분 함수. 이것들은 아마도 기능에 대한 기본값을 지정하는 더 "기능적"이고 더 유연한 방법입니다.
필요한 경우 기본 매개 변수로 제공하려는 매개 변수가있는 함수를 작성하여 (필요한 경우) 시작하십시오.
(defn string->integer [base str]
(Integer/parseInt str base))
Clojure의 버전 partial
에서는 함수 정의에 나타나는 순서대로 "기본"값을 제공 할 수 있기 때문에 수행 됩니다. 원하는대로 매개 변수를 주문한 후 함수를 사용하여 "기본"버전의 함수를 작성할 수 있습니다 partial
.
(partial string->integer 10)
이 함수를 여러 번 호출 할 수있게하려면 다음을 사용하여 var에 넣을 수 있습니다 def
.
(def decimal (partial string->integer 10))
(decimal "10")
;10
다음을 사용하여 "로컬 기본값"을 만들 수도 있습니다 let
.
(let [hex (partial string->integer 16)]
(* (hex "FF") (hex "AA")))
;43350
부분 함수 접근 방식은 다른 함수에 비해 한 가지 중요한 이점이 있습니다. 함수 소비자 는 함수 정의를 수정하지 않고도 함수 생성자 대신 기본값을 결정할 수 있습니다 . 이것은 기본 기능 이 내가 원하는 것이 아니라고 결정한 예제와 함께 설명됩니다 .hex
decimal
이 접근 방식의 또 다른 장점은 기본 기능에 더 설명적이고 다른 범위 (var, local) 일 수있는 다른 이름 (10 진수, 16 진수 등)을 지정할 수 있다는 것입니다. 원하는 경우 부분 기능을 위의 방법 중 일부와 혼합 할 수도 있습니다.
(defn string->integer
([s] (string->integer s 10))
([base s] (Integer/parseInt s base)))
(def hex (partial string->integer 16))
(이 응답의 맨 위에 주어진 이유로 매개 변수의 순서가 바뀌 었으므로 이것은 Brian의 답변과 약간 다릅니다.)
https://clojuredocs.org/clojure.core/fnil을 볼 수도 있습니다.(fnil)
(recur s 10)
사용하여 두 번째 줄이 더 좋을 것이라고 생각합니다 . 그러면 향후 함수 이름을 쉽게 바꿀 수 있습니다. 이 상황에서 사용하지 않는 이유를 아는 사람 이 있습니까?recur
string->integer
recur