在没有抛出断言的情况下,在Clojure中检查nil的函数参数的一种不那么繁琐的模式?

时间:2017-01-10 17:53:46

标签: clojure

这被问到here,但答案都是不可接受的。

我正在尝试将一些防御性编程技术应用于clojure,而且我发现了一些繁琐的事情。

像检查函数参数一样:

(defn my-tolower [s]
  (if (nil? s) nil
               (.toLowerCase s)
               ))

有更简洁的方法吗?

我知道:pre,但会引发异常。

3 个答案:

答案 0 :(得分:4)

您似乎只想要some->,不是吗?

(defn my-tolower [s]
  (some-> s .toLowerCase))

(my-tolower "HELLO") => "hello"
(my-tolower     nil) => nil

或者只是在没有包装函数的情况下内联它:

(some-> "HELLO" .toLowerCase)   => "hello"
(some->  nil    .toLowerCase)   => nil

答案 1 :(得分:1)

由于nil是假的,您可以使用when

(when s (.toLowerCase s))

如果您想要测试,可以使用some?代替nil?

(if (some? s) (.toLowerCase s))

答案 2 :(得分:1)

还有其他方法:

fnil ,可能就是我要做的事情

clojure.core/fnil
([f x] [f x y] [f x y z])
  Takes a function f, and returns a function that calls f, replacing
  a nil first argument to f with the supplied value x. Higher arity
  versions can replace arguments in the second and third
  positions (y, z). Note that the function f can take any number of
  arguments, not just the one(s) being nil-patched.

为接受fn的nil提供默认值。 /

(let [f (fnil str/lower-case "")]
  (f nil))
""

或捕捉NPE

(let [f str/lower-case] 
  (try (f nil) 
    (catch NullPointerException ne nil)))
""

或仅str

(.toLowerCase (str nil))
""

替代defprotocolextend-protocol可能