神刀安全网

Records in Clojure

I haven’t used records before in a project and when reading some code that used it, realize I should learn about records. It’s not complicated and actually kind of cool! Here’s my experimentation.

I re-read the first chapter inClojureApplied where it talks about Modeling your Entities.

I take my Recipe concept and play around at the repl:

user=> (defrecord Recipe [name link source]) user.Recipe

When you create a record, you get two factory functions for free to create instances of it. The first, a positional function:

user=> (def tacos (->Recipe "Tacos" "www.tacorecipes.com" "mom")) #'user/tacos

You must put values for all the fields in or you get

user=> (def tacos (->Recipe "Tacos" "www.tacorecipes.com"))  CompilerException clojure.lang.ArityException: Wrong number of args (2) passed to: user/eval10000/->Recipe--10017, compiling:(form-init4856550892047924668.clj:1:12)

The other way you can create an instance of a record is using a map.

user=> (def pizza (map->Recipe {:name "Pizza" :source "dad"})) #'user/pizza user=> pizza #user.Recipe{:name "Pizza", :link nil, :source "dad"}

We didn’t have a value for link in the map so it still let us create the instance and automatically assigned the value of nil. This might be a reason to use the map-> version over the positional version, if you don’t know all the values at that time. You can always add in missing values later with assoc :

user=> (assoc pizza :link "www.pizzarecipes.com") #user.Recipe{:name "Pizza", :link "www.pizzarecipes.com", :source "dad"}

Accesing the the values in a record is just like a map:

user=> (:name tacos) "Tacos" user=> (:source tacos) "mom"

The chapter has a great section on why you would want to choose Records over Maps you should read! I won’t spoil the fun here, but there are some compelling reasons when to use records over a map.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Records in Clojure

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮