local-variables - una - variables locales ejemplos
Usando argumentos de función como variables locales (9)
Como regla general, no usaría un parámetro de función como una variable de procesamiento local, es decir, trato los parámetros de función como de solo lectura.
En mi opinión, el código comprensible de manera intuitiva es primordial para el mantenimiento, y la modificación de un parámetro de función para usarlo como una variable de procesamiento local tiende a ir en contra de ese objetivo. He llegado a esperar que un parámetro tenga el mismo valor en el medio y en la parte inferior de un método como lo hace en la parte superior. Además, una variable de procesamiento local con nombre apropiado puede mejorar la comprensibilidad.
Aún así, como dice @Stewart, esta regla es más o menos importante dependiendo de la longitud y la complejidad de la función. Para funciones simples cortas como la que se muestra, simplemente usar el parámetro en sí puede ser más fácil de entender que introducir una nueva variable local (muy subjetiva).
Sin embargo, si tuviera que escribir algo tan simple como
countDigits()
, tendería a usar una variable de procesamiento localremainingBalance
countDigits()
en lugar de modificar el parámetronum
como parte del procesamiento local, simplemente me parece más claro.A veces, modificaré un parámetro local al comienzo de un método para normalizar el parámetro:
void saveName(String name) { name = (name != null ? name.trim() : ""); ... }
Racionalizo que esto está bien porque:
a. Es fácil de ver en la parte superior del método,
segundo. el parámetro mantiene su intención conceptual original, y
do. El parámetro es estable para el resto del método.
Entonces, de nuevo, la mitad del tiempo, soy igual de apto para usar una variable local de todos modos, solo para obtener un par de
final
adicionales (está bien, esa es una mala razón, pero me gusta lafinal
):void saveName(final String name) { final String normalizedName = (name != null ? name.trim() : ""); ... }
Si, el 99% del tiempo, el código deja los parámetros de la función sin modificar (es decir, los parámetros de mutación no son intuitivos o inesperados para este código base), durante ese otro 1% del tiempo, se omite un comentario rápido sobre un parámetro de mutación en la parte superior de una función larga / compleja podría ser una gran ventaja para la comprensibilidad:
int CountDigits(int num) { // num is consumed int count = 1; while (num >= 10) { count++; num /= 10; } return count; }
PS :-)
parámetros vs argumentos http://en.wikipedia.org/wiki/Parameter_(computer_science)#Parameters_and_arguments
Estos dos términos a veces se usan indistintamente de manera indistinta; en particular, "argumento" se usa a veces en lugar de "parámetro". Sin embargo, hay una diferencia. Correctamente, los parámetros aparecen en las definiciones de procedimiento; Los argumentos aparecen en las llamadas de procedimiento.
Asi que,
int foo(int bar)
bar
es un parámetro.
int x = 5
int y = foo(x)
El valor de x
es el argumento para el parámetro de bar
.
Algo como esto (sí, esto no se ocupa de algunos casos de borde, ese no es el punto):
int CountDigits(int num) { int count = 1; while (num >= 10) { count++; num /= 10; } return count; }
¿Cuál es tu opinión sobre esto? Es decir, usando argumentos de función como variables locales.
Ambos se colocan en la pila y, en términos de rendimiento más o menos idéntico, me pregunto sobre los aspectos de las mejores prácticas de esto.
Me siento como un idiota cuando agrego una línea adicional y bastante redundante a esa función que consiste en int numCopy = num
, sin embargo me molesta.
¿Qué piensas? ¿Debería evitarse esto?
Creo que las mejores prácticas de esto varían según el idioma. Por ejemplo, en Perl puede localize cualquier variable o incluso parte de una variable en un ámbito local, de modo que cambiarla en ese ámbito no tendrá ningún efecto fuera de ella:
sub my_function
{
my ($arg1, $arg2) = @_; # get the local variables off the stack
local $arg1; # changing $arg1 here will not be visible outside this scope
$arg1++;
local $arg2->{key1}; # only the key1 portion of the hashref referenced by $arg2 is localized
$arg2->{key1}->{key2} = ''foo''; # this change is not visible outside the function
}
De vez en cuando me han mordido al olvidar localizar una estructura de datos que se pasó por referencia a una función, que cambié dentro de la función. A la inversa, también devolví una estructura de datos como un resultado de función que se compartió entre varios sistemas y la persona que llama luego procedió a cambiar los datos por error, afectando a estos otros sistemas en un problema difícil de rastrear, generalmente llamado acción a distancia . Lo mejor que podría hacer aquí sería hacer un clon de los datos antes de devolverlos *, o hacerlo de solo lectura **.
* En Perl, vea la función dclone()
en el módulo dclone()
incorporado.
** En Perl, vea lock_hash()
o lock_hash_ref()
en el módulo integrado Hash::Util ).
El código debe ser lo más autosuficiente posible. Lo que quiero decir con esto es que ahora tiene una dependencia de lo que se pasa como parte de su algoritmo. Si otro miembro de su equipo decide cambiar esto a un pase por referencia, entonces podría tener grandes problemas.
La mejor práctica es definitivamente copiar los parámetros de entrada si espera que sean inmutables.
El estándar de codificación de mi equipo recomienda esto porque puede salirse de control. En mi opinión, para una función como la que usted muestra, no duele porque todos pueden ver lo que está sucediendo. El problema es que con el tiempo las funciones se vuelven más largas y tienen correcciones de errores en ellas. Tan pronto como una función tiene más de una pantalla llena de código, esto comienza a ser confuso, por eso nuestro estándar de codificación lo prohíbe.
El compilador debe poder deshacerse de la variable redundante con bastante facilidad, por lo que no tiene impacto en la eficiencia. Probablemente sea solo entre usted y su revisor de código si esto está bien o no.
Generalmente no cambiaría el valor del parámetro dentro de la función. Si en algún punto posterior de la función necesita referirse al valor original, todavía lo tiene. en su caso simple, no hay problema, pero si agrega más código más adelante, puede referirse a ''num'' sin darse cuenta de que se ha cambiado.
Normalmente no modifico los parámetros de la función, a menos que sean punteros, en cuyo caso podría alterar el valor al que se apunta.
Si no necesito una copia del valor original, no declaro una nueva variable.
En mi opinión, no creo que mutar los valores de los parámetros sea una mala práctica en general,
Depende de cómo lo vayas a utilizar en tu código.
Siempre me parece un poco gracioso cuando hago esto, pero esa no es realmente una buena razón para evitarlo.
Una razón por la que posiblemente desee evitarlo es por motivos de depuración. Ser capaz de distinguir la diferencia entre las variables del "bloc de notas" y la entrada a la función puede ser muy útil cuando está a mitad de la depuración.
No puedo decir que sea algo que se presente con mucha frecuencia en mi experiencia, y que a menudo puede encontrar que vale la pena introducir otra variable solo por tener un nombre diferente, pero si el código que es más limpio termina cambiando el valor De la variable, que así sea.
Una situación en la que esto puede surgir y ser completamente razonable es cuando tiene algún valor que significa "usar el valor predeterminado" (normalmente una referencia nula en un lenguaje como Java o C #). En ese caso, creo que es completamente razonable modificar el valor del parámetro al valor predeterminado "real". Esto es particularmente útil en C # 4, donde puede tener parámetros opcionales, pero el valor predeterminado debe ser una constante:
Por ejemplo:
public static void WriteText(string file, string text, Encoding encoding = null)
{
// Null means "use the default" which we would document to be UTF-8
encoding = encoding ?? Encoding.UTF8;
// Rest of code here
}
Sobre C y C ++ :
Mi opinión es que usar el parámetro como una variable local de la función está bien porque ya es una variable local. ¿Por qué entonces no usarlo como tal?
También me siento tonto al copiar el parámetro en una nueva variable local solo para tener una variable modificable con la que trabajar.
Pero creo que esta es una opinión bastante personal. Hazlo como quieras. Si sientes que todavía estás copiando el parámetro debido a esto, eso indica que a tu personalidad no le gusta y entonces no debes hacerlo.