2010-09-16 18 views
5

Tengo una función que devuelve una matriz, y me gustaría obtener solo el primer elemento de esa matriz sin declarar una variable para la matriz. Básicamente, debe ser algo como:¿Cómo obtengo el primer elemento de una función que devuelve una matriz en Perl?

functionReturningArray()[1]

Excepto eso no funciona.

Realmente no quiero perder espacio declarando todo el conjunto ya que no lo necesito, y prefiero no perder una línea adicional de código. De todos modos para hacer esto en una línea?

Respuesta

12
my $item = (function_returning_list())[0]; 

Las funciones no pueden devolver matrices, pueden devolver el contenido de una matriz (es decir, una lista). Las listas se indexan comenzando en 0, por lo que el primer elemento del retorno de una función es (func)[0]. También se podría decir

my ($item) = function_returning_list(); 

Esto pone function_returning_list en el contexto de lista y hace la asignación (en orden) a las variables de la lista de la mano izquierda.

Es importante señalar que

sub function_returning_list { 
    return ("a", "b", "c") 
} 

my $item = function_returning_list(); 

probable es que no va a hacer lo que usted espera. La variable $item se le asignará "c". Esto se debe a que no existe una lista en contexto escalar. En cambio, tiene el operador de coma en contexto escalar, y eso evalúa la expresión de la izquierda en el contexto vacío, descarta el resultado y luego evalúa el lado derecho en contexto escalar.

Llamo una secuencia (en lugar de una lista) y es útil si hay algunas situaciones como C-style for loops.

+8

No existe una lista en contexto escalar. No existe una lista en contexto escalar. No existe una lista en contexto escalar. No existe una lista en contexto escalar. No existe una lista en contexto escalar. No existe una lista en contexto escalar. No existe una lista en contexto escalar. No existe una lista en contexto escalar. –

+2

Tiene el operador de coma en contexto escalar.Consulte [Conozca la diferencia entre una lista y una matriz] (http://www.effectiveperlprogramming.com/blog/39) –

+0

@brian d foy Eso es lo que "Se llama secuencia (en lugar de lista)". El concepto de una lista en contexto escalar es una mentira útil. Es mucho más fácil de explicar a la gente. Especialmente en situaciones como 'sub f {return @a} my $ x = f();' donde no hay coma a la vista. –

2

Primero, [1] es el segundo elemento en la lista ya que Perl usa índices basados ​​en 0.

En segundo lugar, necesita que el retorno de la función se evalúe en el contexto de la lista para tener una lista para acceder.

(functionReturningArray())[0] 
2

Yendo un paso más allá de la discusión debajo de la respuesta de Chas, no hay tal cosa como un período de lista.

A diferencia de Python, que tiene el tipo de tupla que cumple este rol, las listas de Perl son completamente una construcción de las pilas en el compilador/intérprete. Es por eso que no puede tomar una referencia a una lista.

Al igual que el uso de tuplas de python, perl automáticamente empuja y cambia su pila para moverse por los grupos de variables cuando se usa una construcción como el operador de asignación =. (Las reglas de precedencia de Perl son las que requieren el paréntesis, ya que = se une más estrictamente que ,). La diferencia de nivel macro entre los mecanismos de Perl y Python es que el contexto se propaga a través de toda la expresión.

Por lo tanto, cuando en contexto escalar, ese contexto se distribuye a cada uno de los operadores , y el operador ejecuta su lado izquierdo en contexto vacío y su lado derecho en contexto escalar que luego devuelve. Sin embargo, en el contexto de la lista, el operador , envía sus argumentos a la pila, todos los cuales se ejecutan en el contexto de la lista. La pila se pasa a través del operador de asignación y luego se desplaza al valor l.La pila/lista en sí misma es inmutable al código de nivel de Perl, sus herramientas de modificación son en realidad todas la sintaxis de Perl.

Si bien es incorrecto hacer referencia a una lista en contexto escalar (porque tal cosa no puede suceder), puede referirse al comportamiento de la lista como construcciones sintácticas (construido por el operador ,, construido por una porción de matriz o list slice). En contexto escalar, el comportamiento de las construcciones de tipo lista es devolver el último elemento de la lista. Cómo se logra esto depende de los operadores en la expresión. esto es, por supuesto, en contraste con el comportamiento de las matrices en contexto escalar que devuelven su longitud.

Para aclarar con un ejemplo y, finalmente, obedecen a las reglas y en realidad responde a la pregunta:

Suponiendo my @array = (10, 11, 12);

  • contexto escalar

    my $val = (10, 11, 12);  # $val is 12 
    my $val = (10 .. 20)[0 .. 5]; # $val is 15  
    my $val = @array;    # $val is 3 
    my $val = function();   # $val is the last executed expression 
    
    • así que si function termina con 10, 11, 12 entonces el valor será 12
    • si en lugar es @array entonces el valor será 3
    • y si termina con 10, 11, 12, @array el valor es también 3

  • contexto lista

    my ($val) = (10, 11, 12);  # $val is 10 
    my ($val) = (10 .. 20)[0 .. 5]; # $val is 10 
    my ($val) = @array;    # $val is 10 
    my ($val) = function();   # $val is the first executed expression 
               # in the last statement. 
    
    • entonces si function termina con 10, 11, 12 entonces el valor wil l sea 10
    • si en lugar es @array entonces el valor será 10
    • y si termina con 10, 11, 12, @array el valor es también 10

  • y para la integridad, el contexto lista agarrar el lista entera en una matriz

    my @val = (10, 11, 12);  # @val is 10, 11, 12 
    my @val = (10 .. 20)[0 .. 5]; # @val is 10, 11, 12, 13, 14, 15 
    my @val = @array;    # @val is 10, 11, 12 
    my @val = function();   # @val is the the last executed statement 
    
    • por lo que si function extremos con 10, 11, 12 entonces @val será de 10, 11, 12
    • si en lugar es @array entonces @val habrá 10, 11, 12
    • y si termina con 10, 11, 12, @array entonces @val habrá 10, 11, 12, 10 , 11, 12
+1

No confunda el idioma con su implementación. –

+0

No veo cómo señalar exactamente qué "listas" están en Perl es confuso, no es como si hubiera alguna otra implementación ... ¿Hay algo de malo con lo que escribí? –

Cuestiones relacionadas