从定义中获取价值

时间:2015-02-28 08:55:28

标签: clojure

我需要建议, 我尝试制作功能:

(def user-map [new-name new-phone new-email]
  {:name new-name
   :phone new-phone
   :email new-email})

使用新名称,新手机,新电子邮件是用户输入。但是当我尝试编译它时,它会说def太多的参数,在更改def到defn之后,当我尝试在REPL中执行用户映射时,我会得到类似

的内容
  

#<temp_atom$user_address zenedu.mm.dbase.temp_atom$user_address@714924b5

而不是实际的地图。

我需要到地图,有什么建议吗?

4 个答案:

答案 0 :(得分:1)

听起来好像你在概念上将从调用user-map返回的值作为一个函数与一些参数组合并自己评估符号user-map。

评估

(user-map "me" "123456789" "me@here.com")

通过在当前命名空间中查找var user-map并使用这些参数调用存储在该var中的函数,将返回一个映射。评估的地方

user-map

只需在当前命名空间中查找var user-map并返回该var的内容,在你使用defn的情况下,它将是它自己的函数。然后REPL打印该功能的对象。

答案 1 :(得分:0)

在您的用例中,您需要defn为您想要的对象定义构建器(如Java中的构造函数)。日志

#<temp_atom$user_address zenedu.mm.dbase.temp_atom$user_address@714924b5

建议您在应用程序中的某个位置使用另一个结构user-address,看起来user-map对象与此user-address之间存在混淆。

无论如何,您可能有兴趣查看defrecord,它提供了一种使用构造函数构建对象的便捷方法(以及可能与此对象相关的其他函数),例如

(defrecord user [name phone email])

defrecord提供了2个构造函数->usermap->user

(def me  (->user "abb" "0102030405" "abb@mail.com"))
(def you  (map->user {:email "das@mail.com" :phone "9090909090" :name "das"}))

您可以通过与地图完全相同的关键字访问用户的属性:

user> (:name me)
"abb"
user> (:phone you)
"9090909090"

答案 2 :(得分:0)

好的,您应该使用defn代替def

但是这里真正有哪些信息?映射键的数量和顺序,在本例中为[:name :phone :email]

将构建的通用函数 - 来自序列 - 函数将从序列构建映射

(defn map-builder [keys]
  (fn [& values] (zipmap keys values)))

然后您可以定义

(def user-map (map-builder [:name :phone :email]))

......按要求运作:

(user-map "me" "123456789" "me@here.com")
;{:email "me@here.com", :phone "123456789", :name "me"}

如果表现紧迫,请务必使用记录而不是地图,如@AbbéRésina suggests

答案 3 :(得分:0)

简单地说......

您收到的错误主要是将向量作为第二个值传递给def。如果你想在这个例子中使用def,请使用...

(def user-map-other
  (fn [new-name new-phone new-email]
    {:name new-name
     :phone new-phone
     :email new-email}))

这里我们使用的是一个接受三个参数的匿名函数。这是一个了解更多关于他们的链接=&gt; http://clojuredocs.org/clojure.core/fn

要访问函数中包含的值,我们可以在此实例中使用get

(get (user-map-other "Ben" "999" "bbb@mail.com") :phone) => "999"
(get (user-map-other "Ben" "999" "bbb@mail.com") :name) => "Ben"
(get (user-map-other "Ben" "999" "bbb@mail.com") :email) => "bbb@mail.com"

更简洁的方法是使用defn,如下所示。

(defn user-map [new-name new-phone new-email]
  {:name new-name
   :phone new-phone
   :email new-email})

(get (user-map "Ben" "999" "bbb@mail.com") :phone) => "999"
(get (user-map "Ben" "999" "bbb@mail.com") :name) => "Ben"
(get (user-map "Ben" "999" "bbb@mail.com") :email) => "bbb@mail.com"