我的函数行为不同,具体取决于哪些关键字参数提供了值.对于这个问题,我想知道根据提供的参数类型,行为略有不同的函数.
示例函数,用于递增列表的每个元素:
(defn inc-list [& {:keys [list-str list]}]
(let [prepared-list (if-not (nil? list) list (clojure.string/split list-str #","))]
(map inc prepared-list)))
Run Code Online (Sandbox Code Playgroud)
做一个多方法而不是测试参数的类型是否有意义?我之前没有使用过多种方法,也不确定正确的时间使用它们.如果这是一个好主意,下面的例子是否有意义?
例:
(defn inc-coll [col] (map inc col))
(defmulti inc-list class)
(defmethod inc-list ::collection [col] (inc-col col))
(defmethod inc-list String [list-str]
(inc-col
(map #(Integer/parseInt %)
(clojure.string/split list-str #",")))
Run Code Online (Sandbox Code Playgroud)
首先要做的事情是:(map 'inc x)将每个项目x作为关联集合处理,并查找由密钥索引的值'inc.
user> (map 'inc '[{inc 0} {inc 1} {inc 2}])
(0 1 2)
Run Code Online (Sandbox Code Playgroud)
你可能想inc代替
user> (map inc [0 1 2])
(1 2 3)
Run Code Online (Sandbox Code Playgroud)
接下来,我们尝试inc一个字符串,args string/split乱序,以及一些拼写错误.
如果您定义了multi to dispatch on class,那么方法应该由Class参数化,而不是关键字占位符.我更改了多功能,因此它适用于任何Clojure知道如何作为seq处理的东西.此外,作为一个bikeshedding,它最好使用type,它提供了区分Clojure代码class中不提供的输入的区别:
user> (type (with-meta {:a 0 :b 1} {:type "foo"}))
"foo"
Run Code Online (Sandbox Code Playgroud)
把它们放在一起:
user> (defn inc-coll [col] (map inc col))
#'user/inc-coll
user> (defmulti inc-list type)
nil
user> (defmethod inc-list String [list-str]
(inc-coll (map #(Integer/parseInt %) (clojure.string/split list-str #","))))
#<MultiFn clojure.lang.MultiFn@6507d1de>
user> (inc-list "1,10,11")
(2 11 12)
user> (defmethod inc-list clojure.lang.Seqable [col] (inc-coll (seq col)))
#<MultiFn clojure.lang.MultiFn@6507d1de>
user> (inc-list [1 2 3])
(2 3 4)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
68 次 |
| 最近记录: |