【问题标题】:Questions about Lists and other stuff in Clojure关于 Clojure 中的列表和其他内容的问题
【发布时间】:2010-11-10 03:30:58
【问题描述】:
我有几个关于 clojure 中的列表、类和变量的问题。
- 这可能看起来很愚蠢,但是如何访问 List 中的元素?
我正在编写一个程序,让您可以操作电话簿;您可以添加条目、删除条目或打印有关条目的信息。这引出了两个问题:
有没有办法创建一个包含“姓名”“地址”“电话号码”变量的“条目”类?或者这在 clojure 中是不可能的(以及一般的函数式编程?)如果我不能拥有包含该信息的对象列表,我将如何完成这项任务?
我正在考虑使用一个函数来读取用户输入以了解用户想要做什么(添加条目、删除条目或打印信息),然后调用适当的函数来执行当回调第一个函数时完成。将条目列表作为参数传递给每个函数是否正确?
【问题讨论】:
标签:
class
list
parameters
clojure
【解决方案1】:
对于您的问题的第一部分,如果您将使用 (nth ...) 访问列表中的项目,您可以考虑使用向量。向量不像其他语言中的数组。例如,除了数字索引之外,将它们切碎并在末尾添加新元素也是有效的。在引擎盖下,数组实际上与地图非常相似。
最好的数组是索引的函数:
(定义 [1 2 3 4])
(a 2) ==> 3
对于第 2 部分和第 3 部分,pmf 的回答很好地涵盖了它们。
【解决方案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】:
这可能看起来很愚蠢,但我如何访问 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)
前者只在map的key为关键字时有效,后者适用于所有类型的key。
因此,对于您的示例,您的数据模型(电话簿)将是此类地图的序列(例如,列表或向量)。
我正在考虑使用一个函数来读取用户输入以了解用户想要做什么(添加条目、删除条目或打印信息),然后调用适当的函数来执行该操作,该函数在完成时回调第一个函数。将条目列表作为参数传递给每个函数是否正确?
由于您的模型仅包含一个主要数据结构(电话簿序列),因此将其作为 arg 传递无疑是设计函数的合适方法。如果您希望拥有更多种类的顶级容器(即,用于更真实的应用程序),我建议您查看Application Context Pattern,一开始看起来有点吓人(至少它对我来说是这样,并且它包含很多 Clojure 特定的行话),但值得努力学习。