Vengo con esto:
(defn string-> integer [str & [base]] (Entero / parseInt str (if (nil? Base) 10 base))) (cadena-> entero "10") (cadena-> entero "FF" 16)
Pero debe ser una mejor manera de hacer esto.
Vengo con esto:
(defn string-> integer [str & [base]] (Entero / parseInt str (if (nil? Base) 10 base))) (cadena-> entero "10") (cadena-> entero "FF" 16)
Pero debe ser una mejor manera de hacer esto.
Una función puede tener múltiples firmas si las firmas difieren en aridad. Puede usar eso para proporcionar valores predeterminados.
(defn string->integer
([s] (string->integer s 10))
([s base] (Integer/parseInt s base)))
Nota que asumiendo false
y nil
son a la vez los no valores considerados, (if (nil? base) 10 base)
se podría acortar a (if base base 10)
, o adicionalmente a (or base 10)
.
(recur s 10)
, usando enrecur
lugar de repetir el nombre de la funciónstring->integer
. Eso facilitaría cambiar el nombre de la función en el futuro. ¿Alguien sabe alguna razón para no usarrecur
en estas situaciones?recur
solo funciona en el mismo arity. si se trató anteriormente se repiten, por ejemplo:java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:
(string->integer s 10)
)?También puede desestructurar
rest
argumentos como un mapa desde Clojure 1.2 [ ref ]. Esto le permite nombrar y proporcionar valores predeterminados para argumentos de función:Ahora puedes llamar
o
Puede ver esto en acción aquí: https://github.com/Raynes/clavatar/blob/master/src/clavatar/core.clj (por ejemplo)
fuente
Esta solución es más cercana al espíritu de la solución original , pero marginalmente más limpia.
Un patrón similar que puede ser útil en
or
combinación conlet
Si bien en este caso es más detallado, puede ser útil si desea que los valores predeterminados dependan de otros valores de entrada . Por ejemplo, considere la siguiente función:
Este enfoque se puede extender fácilmente para trabajar con argumentos con nombre (como en la solución de M. Gilliar) también:
O usando aún más de una fusión:
fuente
or
or
es diferente de:or
yaor
que no conoce la diferencia denil
yfalse
.Hay otro enfoque que puede considerar: funciones parciales . Podría decirse que es una forma más "funcional" y más flexible de especificar valores predeterminados para funciones.
Comience creando (si es necesario) una función que tenga los parámetros que desea proporcionar como predeterminados como los parámetros principales:
Esto se hace porque la versión de Clojure le
partial
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 según lo deseado, puede crear una versión "predeterminada" de la función utilizando lapartial
función:Para hacer que esta función sea invocable varias veces, puede ponerla en una variable usando
def
:También puede crear un "valor predeterminado local" usando
let
:El enfoque de función parcial tiene una ventaja clave sobre los demás: el consumidor de la función aú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 el
hex
que he decidido que la función predeterminadadecimal
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 un alcance diferente (var, local). La función parcial también se puede mezclar con algunos de los enfoques anteriores si se desea:
(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 figuran en la parte superior de esta respuesta)
fuente
También puede consultar
(fnil)
https://clojuredocs.org/clojure.core/fnilfuente