模式匹配或多态分派在clojure中作为条件结构可用吗?

模式匹配或多态分派在clojure中作为条件结构可用吗?,clojure,Clojure,在静态语言中,我可以 在像erlang这样的语言中,我可以使用模式匹配而不是if-else 在clojure中我可以使用什么?您想要使用多种方法。这是一篇很好的文章,介绍了如何使用这些工具。 模式匹配和多态分派都可用 多态调度的两种形式是多方法和协议 leontalbot给出了一个关于多方法的好例子,该方法基于参数的某些特定属性(可以是类型,但可以使用不同的分派函数)分派到特定的实现。换句话说,要决定使用哪个实现,multimethod对参数执行一个函数,并将其与dispatch表进行比较 下

在静态语言中,我可以

在像erlang这样的语言中,我可以使用模式匹配而不是if-else


在clojure中我可以使用什么?

您想要使用多种方法。这是一篇很好的文章,介绍了如何使用这些工具。

模式匹配和多态分派都可用

多态调度的两种形式是多方法和协议

leontalbot给出了一个关于多方法的好例子,该方法基于参数的某些特定属性(可以是类型,但可以使用不同的分派函数)分派到特定的实现。换句话说,要决定使用哪个实现,multimethod对参数执行一个函数,并将其与dispatch表进行比较

下面是另一个例子:

;声明多重方法:
(defmulti get length类)
; 提供具体类型的实现:
(defmethod get length java.lang.String[str](.length str))
(defmethod get length java.lang.Number[num](.length(str num)))
; 为字符串调用它:
(获取长度“Hello”);=>5.
; 为数字调用它(因为Long是数字的子类型,所以有效):
(获取长度1234);=>4.
我们在这里使用一些简单的例子来保持简单,但是dispatch函数可能更有趣。另一个例子是,假设我们希望选择基于输入长度的排序算法:

(defn选择impl[in]
(续)
(已排序?输入):已排序
(<(计数)10):气泡
:其他:快速排序)
(defmulti my sort choose impl)
(defmethod my sort:sorted[in]in)
(defmethod my sort:bubble[in](my bubble sort in))
(defmethod my sort:quicksort[in](my quicksort in))
这个是人为设计的,您可能不会以这种方式实现它,但我希望它是使用不同分派函数的好例子

协议是另一回事,更像是Java和其他OO语言的接口。您定义一组构成协议的操作,然后提供各种类型的实现

;协议规范:
(定义我的长度(获取长度[x]))
; 记录可以实现协议:
(defrecord我的常量记录[值]
我的长度
(获取长度[x]值)
; 我们也可以“扩展”现有类型以支持协议:
(延长我的长度
java.lang.String
(获取长度[x](.length x))
java.lang.Long
(获取长度[x](.length(.toString x)))
; 现在,调用get length将为以下各项找到正确的实现:
(获取长度(我的常量记录.15));=>15
(获取长度“123”);=>3.
(获取长度1234);=>4.
最后,模式匹配可从非常流行的库中获得:

(doseq[n(范围1101)]
(println
(匹配[(第3款)(第5款)]
[0]“嘶嘶作响”
[0}“嘶嘶作响”
[\u0]“嗡嗡声”
:其他(n)

也许吧?实际上,这是Clojure版本的多态性。这个问题对于模式匹配的答案来说实在太宽泛了:是的,这是超宽泛的。多方法和协议都以本文描述的方式“替换if”。此外,clojure能够生成java类的子类或实现java接口的类,它们的行为类似
fnil
取代了if检查,可选的第三个参数get(映射的第二个参数或函数位置中使用的关键字)@soulcheck&noise如果你们认为这个问题太宽泛,为什么不投票将其作为太宽泛的问题搁置?似乎有一个bug:根据,“一只空载的欧洲燕子的平均巡航空速约为每秒11米,或每小时24英里”。@bereal好吧,我想在这里举一个简单的例子,说明多种方法是如何工作的。如果你想得到“bereal”的答案,请建议也对非洲和挪威的速度进行编辑。;-)
(def speed 24)

(defmulti get-speed :type)

(defmethod get-speed :european       [_] speed)
(defmethod get-speed :african        [_] (+ speed 2))
(defmethod get-speed :norwegian-blue [_] (* speed 1.05))

(get-speed {:type :european}) 
; => 200