DAY 8
0
Software Development

# 繫結與函式（二）

## 函式

### 多載

``````(defn adder
([x y] (+ x y)))
;; => 13
;; => 5
``````

### 不定長度參數

``````(defn str-all-numbers [x & rest]
(apply str "Hi " rest))
;; => #'user/str-all-numbers
(str-all-numbers 0 1 2 3 4)
;; => “Hi 1234”
(str-all-numbers 0)
;; => “Hi ”
``````

``````(defn overloading-variadic
([] 0)
([x] 1)
([x y] 2)
([x y & rest] "many arguments"))
;; => 0
;; => 1
;; => 2
;; => "many arguments"
``````

### 解構

``````(defn useless-adder [lst]
(let [x (first (rest lst))
y (first (rest (rest (rest lst))))]
(+ x y)))
(useless-adder [1 3 5 7 9])
;; => 10
``````

#### 向量解構

``````(let [[_ x _ y] [1 3 5 7 9]]
(+ x y))
;; => 10
``````

``````(let [[_ _ [x y]] [1 2 [3 4] 5]]
(* x y))
;; => 12
``````

``````(let [[x y :as original] [1 2 3 4 5]]
(conj original (+ x y)))
;; => [1 2 3 4 5 3]
``````

``````(let [[x & rest] [10 20 30 40 50]]
rest)
;; => (20 30 40 50)
``````

``````(let [[x & rest :as original] [2 4 6 8 10]]
(println "x:" x ", rest:" rest ", original:" original))
;; => x: 2 , rest: (4 6 8 10) , original: [2 4 6 8 10]
``````

``````(defn useful-adder [[_ x _ y]]
(+ x y))
(useful-adder [1 3 5 7 9])
;; => 10
``````

#### 映射解構

``````(def m {:a 5 :b 10 "c" 15})
;; => #'user/m
(let [{a :a b :b} m]
(+ a b))
;; => 15
``````

`a` 匹配索引鍵 `:a` 對應的資料、`b` 匹配索引鍵 `:b` 對應的資料。找不到對應的資料，會得到預設的 `nil`，如果不想使用預設的 `nil`，亦可以透過 `:or` 指定當某索引鍵找不到資料時，預設取得的資料：

``````(def m {:a 5 :b 10 "c" 15})
;; => #'user/m
(let [{a :a b :b d :d :or {d "OH"}} m]
(println a b d))
;; => 5 10 OH
``````

``````(let [{a :a b :b :as whole} m]
(println a b whole))
;; => 5 10 {:a 5, :b 10, c 15}
``````

``````(def m {:a 10 :b 20 :c 15})
;; => #'user/m
(let [{:keys [a b]} m]
(println a b))
;; => 10 20
``````

``````(let [{:strs [a d]} {"a" "A", "b" "B", "c" "C", "d" "D"}]
(println a d))
;; => A D
(let [{:syms [a d]} {'a "A", 'b "B", 'c "C", 'd "D"}]
(println a d))
;; => A D
``````

``````(defn greet-user [{:keys [first-name last-name]}]
(println "Welcome," first-name last-name))
;; => #'user/greet-user
(def catherine {:first-name "Catherine", :last-name "Chen", :age 40})
;; => #'user/catherine
(greet-user catherine)
;; => Welcome, Catherine Chen
``````

（未完待續）