我对clojure中的列表,类和变量有几个问题。
我正在编写一个允许您操作电话簿的程序;您可以添加条目,删除条目或打印有关条目的信息。这引出了两个问题:
有没有办法创建一个包含“名称”“地址”“电话号码”变量的“条目”?或者在clojure中是不可能的(通常是函数式编程?)如果我不能拥有包含该信息的对象列表,我将如何进行此任务?
我正在考虑使用一个函数来读取用户输入以了解用户想要做什么(添加条目,删除条目或打印信息)然后调用相应的函数来执行回调第一个函数的函数完成。作为参数传递每个函数的条目列表是正确的事情吗?
答案 0 :(得分:7)
这看起来很愚蠢,但如何访问List中的元素?
(nth coll index)
例如:
(nth [1 2 3 4] 2) ; -> 3 (since it uses zero-based indexing)
有没有办法创建一个包含“名称”“地址”“电话号码”变量的“条目”?或者在clojure中是不可能的(通常是函数式编程?)如果我不能拥有包含该信息的对象列表,我将如何进行此任务?
这在Clojure中是可能的,但却是单一的。在Clojure中,数据实体的基本抽象是映射,而不是类(除了需要与Java框架直接互操作的一些极端情况)。所以你只需要使用地图:
(def entry {:name "x" :address "y" :phone-number "z"})
要访问该项目的名称,请使用
(:name entry)
或
(get entry :name)
前者仅在地图的关键字是关键字时起作用,后者适用于所有类型的关键字。
因此,对于您的示例,您的数据模型(电话簿)将是此类地图的seq(例如,列表或向量)。
我正在考虑使用一个函数来读取用户输入以了解用户想要做什么(添加条目,删除条目或打印信息)然后调用相应的函数来执行该操作,该函数在完成后回调第一个函数。作为参数传递每个函数的条目列表是正确的事情吗?
由于您的模型只包含一个主要数据结构(电话簿seq),因此将其作为arg传递肯定是设计函数的合适方法。如果您希望有更多种类的顶级容器(例如,对于更真实的世界应用程序),我建议您查看Application Context Pattern,这看起来有点令人生畏(至少它对我有用) ,它包含了许多特定的Clojure术语,但值得学习。
答案 1 :(得分:5)
您是否考虑过购买这本书Programming Clojure? pdf版只需21美元。在我看来非常物有所值。
答案 2 :(得分:2)
(entry :name)
访问地图时,也可以正常工作。因此,您有三种方法可以使用关键字访问地图元素:
(entry :name)
或
(:name entry)
或
(get entry :name)
,其中
(def entry {:name "x" :address "y" :phone-number "z"})
正如Rayne所提到的,只有当密钥是关键字时才能使用第二种形式。您可以将其他“短”表单与其他类型的键一起使用:
user=>(def my-map {"a" "b" "c" "d"})
user=>(my-map "c")
"d"
user=>(get my-map "a")
"b"
答案 3 :(得分:1)
对于您的问题的第一部分,如果您将使用(第n ...)访问列表中的项目,您可以考虑使用向量。向量与其他语言中的数组不同。例如,除了数字索引之外,砍掉它们并向末尾添加新元素也是有效的。在引擎盖下,阵列实际上非常类似于地图。
所有数组中最好的是索引函数:
(def a [1 2 3 4]) (a 2) ==> 3
对于第2和第3部分,pmf的答案很好地涵盖了它们。