How to make a record from a sequence of values

后端 未结 5 1319
执笔经年
执笔经年 2020-12-20 13:38

I have a simple record definition, for example

(defrecord User [name email place])

What is the best way to make a record having it\'s value

5条回答
  •  一个人的身影
    2020-12-20 13:58

    Writing your own constructor function is probably the way to go. As Arthur Ulfeldt said, you then have a function you can use as a function (e.g. with apply) rather than a Java-interop constructor call.

    With your own constructor function you can also do argument validation or supply default arguments. You gain another level of abstraction to work with; you can define make-user to return a hash-map for quick development, and if you later decide to change to records, you can do so without breaking everything. You can write constructors with multiple arities, or that take keyword arguments, or do any number of other things.

    (defn- default-user [name]
      (str (.toLowerCase name) "@example.com"))
    
    (defn make-user
      ([name] (make-user name nil nil))
      ([name place] (make-user name nil place))
      ([name user place]
         (when-not name
           (throw (Exception. "Required argument `name` missing/empty.")))
         (let [user (or user (default-user name))]
           (User. name user place))))
    
    (defn make-user-keyword-args [& {:keys [name user place]}]
      (make-user name user place))
    
    (defn make-user-from-hashmap [args]
      (apply make-user (map args [:name :user :place])))
    
    user> (apply make-user ["John" "john@example.com" "Somewhere"])
    #:user.User{:name "John", :email "john@example.com", :place "Somewhere"}
    
    user> (make-user "John")
    #:user.User{:name "John", :email "john@example.com", :place nil}
    
    user> (make-user-keyword-args :place "Somewhere" :name "John")
    #:user.User{:name "John", :email "john@example.com", :place "Somewhere"}
    
    user> (make-user-from-hashmap {:user "foo"})
    ; Evaluation aborted.
    ; java.lang.Exception: Required argument `name` missing/empty.
    

提交回复
热议问题