iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
自我挑戰組

從零開始的 clojure系列 第 20

Day 20 Clojure - Function- Defining Functions with Docstrings, Parameters and Arity

  • 分享至 

  • xImage
  •  

前言

大家好,我是對於 Clojure 一無所知的菜鳥小白工程師。

今天我們要來學習在定義函數時的「文檔字符串」(docstring) 以及「參數和參數個數」(parameters and arity)。

try Clojure here: https://qa-mktg.codingrooms.com/compiler/clojure/

Docstrings

文檔字符串(docstrings),它是一種描述性的說明,通常位於函數或類別的開頭,用於提供對程式碼的說明,幫助其他開發者或使用者了解該程式碼的作用和使用方法。

我們可以在REPL(Read-Eval-Print Loop)中查看函數的文檔字符串,方法是使用 (doc 函數名稱),例如 (doc map)

(doc map)
;=>
;clojure.core/map
;([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
;Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments. Returns a transducer when no collection is provided.

Parameters and Arity

在程式設計中, Parameters and Arity(參數和參數個數) 是指函數可以接受的輸入以及這些輸入的數量。參數是函數接收的值,而參數個數(也就是arity)則是描述函數可以接受幾個參數的特性。

不同的函數可以有不同的參數數目,這樣它們的 arity 就不同。一個函數可以是無參數的(0-arity),也可以是有一個(1-arity)、兩個(2-arity)或多個參數的。

在 Clojure 中,函數可以定義為零個或多個參數。以下舉一些具有不同 arity 的函數定義:

(defn no-params
  []
  "我不需要任何參數!")
;=> (no-params)
;=> "我不需要任何參數!"
  
(defn one-param
  [x]
  (str "我需要一個參數: " x))
;=> (one-param "我是參數")
;=> "我需要一個參數: 我是參數"
  
(defn two-params
  [x y]
  (str "兩個參數!這算什麼!我會將它們合併在一起,嘲笑你! " x y))
;=> (two-params "我是參數1" "我是參數2")
;=> "兩個參數!這算什麼!我會將它們合併在一起,嘲笑你! 我是參數1我是參數2"

在上述例子中, no-params 是一個 0-arity 函數, one-param1-arity,而 two-params2-arity

Arity Overloading

在 Clojure 中,函數重載 / 參數個數重載(artiy overloading)指一個函數可以有多個版本,每個版本接受不同數量的參數。

當我們呼叫這個函數時,Clojure 會根據傳入的參數數量來選擇適合的函數版本執行。這樣的特性使得函數更具彈性,可以處理不同數量的參數輸入,而不需要使用不同名稱的函數。

(defn multi-arity
  ;; 3個參數和主體
  ([第一參數 第二參數 第三參數]
     (執行操作 第一參數 第二參數 第三參數))
  ;; 2個參數和主體
  ([第一參數 第二參數]
     (執行操作 第一參數 第二參數))
  ;; 1個參數和主體
  ([第一參數]
     (執行操作 第一參數)))

我們來看一個範例:

; define 一個方法 x-chop
(defn x-chop
  "描述你對某人施加的攻擊類型"
  ([名字 攻擊類型]
     (str "我用 " 攻擊類型 " 打 " 名字 "!接招!"))
  ([名字]
     (x-chop 名字 "拳頭"))) ;拳頭是預設值

如果我用兩個參數呼叫:

(x-chop "小明" "巴掌")
;=> "我用 巴掌 打 小明!接招!"

如果我用一個參數呼叫:

(x-chop "大明")
;=> "我用 拳頭 打 大明!接招!"

透過定義參數,我們可以讓函數回傳完全不一樣的操作(當然在實作中我們不會這樣做) ,我們再看一個範例:

(defn weird-arity
  ([]
     "Destiny dressed you this morning, my friend, and now Fear is
     trying to pull off your pants. If you give up, if you give in,
     you're gonna end up naked with Fear just standing there laughing
     at your dangling unmentionables! - the Tick")
  ([number]
     (inc number)))

我們不傳入參數直接呼叫,它回傳了一段字串:

(weird-arity)

;=> "Destiny dressed you this morning, my friend, and now Fear is trying to pull off your pants. If you give up, if you give in, you're gonna end up naked with Fear just standing there laughing at your dangling unmentionables! - the Tick"

我們傳入一個參數呼叫,它將執行 inc 函數:

(weird-arity 2)
;=> 3

; inc 是一個內建的函數,用來對數字進行加一操作。它只接受一個數字作為參數,並返回該數字加一後的結果

小結

今天我們學習了在 clojure 中定義一個有效的函數後,更進一步去了解「文檔字符串」(docstring) 以及「參數和參數個數」(Parameters and Arity)的用法。

下一章節,我們將學習解構(Destructuring)!

參考文章


上一篇
Day 19 Clojure - Function- Defining Functions
下一篇
Day 21 Clojure - Function- Destructuring
系列文
從零開始的 clojure23
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言