3

我有几个关于 clojure 中的列表、类和变量的问题。

  1. 这可能看起来很愚蠢,但我如何访问 List 中的元素?

我正在编写一个允许您操作电话簿的程序;您可以添加条目、删除条目或打印有关条目的信息。这引出了两个问题:

  1. 有没有办法创建一个包含“姓名”“地址”“电话号码”变量的类“条目”?还是在clojure(以及一般的函数式编程中)这是不可能的?如果我不能有一个包含该信息的对象列表,我将如何完成这项任务?

  2. 我正在考虑使用一个函数来读取用户输入以了解用户想要做什么(添加条目、删除条目或打印信息),然后调用适当的函数来执行该操作,该函数在完成时回调第一个函数。将条目列表作为参数传递给每个函数是正确的做法吗?

4

4 回答 4

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)

前者仅在地图的键是关键字时才有效,后者适用于所有类型的键。

因此,对于您的示例,您的数据模型(电话簿)将是此类地图的序列(例如,列表或向量)。

我正在考虑使用一个函数来读取用户输入以了解用户想要做什么(添加条目、删除条目或打印信息),然后调用适当的函数来执行该操作,该函数在完成时回调第一个函数。将条目列表作为参数传递给每个函数是正确的做法吗?

由于您的模型仅包含一个主要数据结构(电话簿序列),因此将其作为 arg 传递无疑是设计函数的合适方法。如果您希望拥有更多种类的顶级容器(即对于更真实的应用程序),我建议您查看Application Context Pattern,它一开始看起来有点吓人(至少它对我来说是这样,并且它包含很多 Clo​​jure 特定的行话),但值得努力学习。

于 2009-07-13T05:09:50.707 回答
5

您是否考虑过购买《Programming Clojure 》这本书?pdf 版本只需 21 美元。在我看来物有所值。

于 2009-07-12T20:15:47.497 回答
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"
于 2009-07-13T14:13:04.117 回答
1

对于您的问题的第一部分,如果您将使用 (nth ...) 访问列表中的项目,您可以考虑使用向量。向量不像其他语言中的数组。例如,除了数字索引之外,将它们切碎并在末尾添加新元素也是有效的。在引擎盖下,数组实际上与地图非常相似。

最好的数组是索引的函数:

(定义 [1 2 3 4])
 (a 2) ==> 3

对于第 2 部分和第 3 部分,pmf 的回答很好地涵盖了它们。

于 2009-07-15T00:22:34.020 回答