2011-06-30 10 views

Respuesta

76

Esto está bien documentado en las entradas para perldoc defined y exists. Aquí hay un resumen rápido:

defined $hash{key} le dice si el valor de la tecla dada está o no definido (es decir, no undef). Úselo para distinguir entre valores indefinidos y valores que son falsos en un contexto booleano como 0 y ''.

exists $hash{key} indica si %hash contiene o no la clave especificada. Úselo para distinguir entre valores indefinidos y no existentes.

Esto es más fácil de ver con un ejemplo. Teniendo en cuenta este hash:

my %hash = (a => 1, b => 0, c => undef); 

Aquí están los resultados de la recuperación,-dad definida, y la existencia:

# key value defined exists 
a   1  1  1 
b   0  1  1 
c  undef  0  1 
d  undef  0  0 

En la práctica, la gente suele escribir simplemente if ($hash{key}) {...} porque (en muchos casos comunes) únicos valores verdaderos son significativos/posibles. Si los valores falsos son válidos, debe agregar defined() a la prueba. exists() se usa con mucha menos frecuencia. El caso más común es probablemente cuando se usa un hash como un conjunto. p.ej.

my %set = map { $_ => undef } 'a' .. 'z'; 

Usando undef para valores de ajuste tiene algunas ventajas:

  1. Se representa con mayor precisión la intención (sólo las teclas son significativas, no los valores).
  2. Todos los valores undef comparten una sola asignación (lo que ahorra memoria).
  3. exists() las pruebas son ligeramente más rápidas (porque Perl no tiene que recuperar el valor, solo determina que hay uno).

También tiene la desventaja de que tiene que usar exists() para verificar la membresía establecida, lo que requiere más tipeo y hará lo incorrecto si la olvida.

Otro lugar donde exists es útil es sondear hash bloqueados antes de intentar recuperar un valor (lo que provocaría una excepción).

+0

Muy bien explicado. –

+0

Además, 'defined' también se puede usar en otros tipos de variables, mientras que' exists' arrojará un error si no se usa en un hash o en una matriz (o una subrutina). – felwithe

4

Como se indica en la perldoc on exists:

Dada una expresión que especifica un elemento de un hash, devuelve true si el elemento especificado en el hash nunca se ha inicializado, incluso si el valor correspondiente no está definido.

Un elemento hash o de matriz solo puede ser verdadero si está definido y definido solo si existe, pero lo contrario no necesariamente es cierto.

Es decir, un hash puede contener un elemento indefinido, y si ese es el caso, el defined -check regresará false, mientras que el exists -check volverá true.

Por lo tanto, debe usar exists si desea saber si existe una entrada determinada en el hash, y defined si desea saber si la entrada dada existe y está definida.

+1

Sí. 'exists' comprueba si el hash contiene la clave dada, pero no su valor, mientras que' defined' busca el valor en la clave dada y ve si está definido o no (y si la clave no existe, devuelve un 'undef', por lo que funciona incluso si la clave no está allí). –

3

Este ejemplo muestra la diferencia. En general, los trabajos definidos para cualquier estructura existen y están relacionados con hash.

my %hash=("1"=>undef); 
print "exists:".exists($hash{"1"})."\n"; 
print "defined:".defined($hash{"1"})."\n"; 

La diferencia es pequeña y no tan obvio, por lo que esperan que la gente se hace un lío con ella.

5

Perl documentation:

Cuando se utiliza en un elemento de hachís, definido dice que si se define el valor, no si existe la clave en el hash. Use existe para este último propósito.

14

defined comprueba el valor de la variable, exists comprueba si se ha declarado previamente/inicializan. Si existe, simple y llanamente

ej .:

$hash{$key} = undef; 
# various return values: 
exists $hash{$key}; # true 
defined $hash{$key}; # false 
$hash{$key};   # false 

$hash{$key} = 0; 
# various return values: 
exists $hash{$key}; # true 
defined $hash{$key}; # true 
$hash{$key};   # false 
exists $hash{$foo}; # false 
+0

Y' define $ hash {$ foo}; # falso' Supongo? –

+2

@Sandra Sí, los valores no inicializados siempre están indefinidos. Piénselo como la diferencia entre la declaración y la inicialización: 'my $ var' existe, y contiene el valor' undef'. 'my $ var = 0' existe, y contiene el valor 0, por lo tanto definido. – TLP

+0

'$ hash {$ key}' devuelve el valor de '$ key'. Si bien esto puede interpretarse como un booleano, no es uno. Su primer ejemplo debería devolver 'undef', el segundo' 0'. –

Cuestiones relacionadas