[Function] Cómo crear un valor predeterminado para el argumento de la función en Clojure


Answers

También puede desestructurar argumentos de rest como un mapa desde Clojure 1.2 [ ref ]. Esto le permite nombrar y proporcionar valores predeterminados para los argumentos de funciones:

(defn string->integer [s & {:keys [base] :or {base 10}}]
    (Integer/parseInt s base))

Ahora puedes llamar

(string->integer "11")
=> 11

o

(string->integer "11" :base 8)
=> 9

Puede ver esto en acción aquí: https://github.com/Raynes/clavatar/blob/master/src/clavatar/core.clj (por ejemplo)

Question

Vengo con esto:

(defn string->integer [str & [base]]
  (Integer/parseInt str (if (nil? base) 10 base)))

(string->integer "10")
(string->integer "FF" 16)

Pero debe ser una mejor manera de hacer esto.




Hay otro enfoque que podría considerar: funciones partial . Se podría decir que son una forma más "funcional" y más flexible de especificar valores predeterminados para las funciones.

Comience por crear (si es necesario) una función que tenga el / los parámetro (s) que desea proporcionar como predeterminado (s) como parámetro (s) principal (es):

(defn string->integer [base str]
  (Integer/parseInt str base))

Esto se hace porque la versión partial de Clojure le permite proporcionar los valores "predeterminados" solo en el orden en que aparecen en la definición de la función. Una vez que los parámetros se han ordenado como se desea, puede crear una versión "predeterminada" de la función usando la función partial :

(partial string->integer 10)

Para hacer que esta función se llame varias veces, podrías ponerla en una var usando def :

(def decimal (partial string->integer 10))
(decimal "10")
;10

También puede crear un "valor predeterminado local" usando let :

(let [hex (partial string->integer 16)]
  (* (hex "FF") (hex "AA")))
;43350

El enfoque de función parcial tiene una ventaja clave sobre los demás: el consumidor de la función puede decidir cuál será el valor predeterminado en lugar del productor de la función sin necesidad de modificar la definición de la función . Esto se ilustra en el ejemplo con hex donde he decidido que la función predeterminada decimal no es lo que quiero.

Otra ventaja de este enfoque es que puede asignar a la función predeterminada un nombre diferente (decimal, hexadecimal, etc.) que puede ser más descriptivo y / o diferente (var, local). La función parcial también puede mezclarse con algunos de los enfoques anteriores si se desea:

(defn string->integer 
  ([s] (string->integer s 10))
  ([base s] (Integer/parseInt s base)))

(def hex (partial string->integer 16))

(Tenga en cuenta que esto es ligeramente diferente de la respuesta de Brian, ya que el orden de los parámetros se ha invertido por las razones que se dan en la parte superior de esta respuesta)




Links