Pregunta

He tropezado con un comportamiento extraño en Lua función de descomprimir

table1 = {true, nil, true, false, nil, true, nil}
table2 = {true, false, nil, false, nil, true, nil}

a1,b1,c1,d1,e1,f1,g1 = unpack( table1 )
print ("table1:",a1,b1,c1,d1,e1,f1,g1)

a2,b2,c2,d2,e2,f2,g2 = unpack( table2 )
print ("table2:",a2,b2,c2,d2,e2,f2,g2)

Salida:

table1: true    nil true    false   nil nil nil
table2: true    false   nil nil nil nil nil

El segundo unpack proporciona parámetros hasta el primer valor nulo. Yo podría vivir con eso. La primera tabla proporciona 4? parámetros con un ser nula en el centro. Dispone de 4 parámetros que no son cero, pero no son la que se muestran.

¿Alguien podría explicar esto? Esto se trató con codepad.org y Lua 5.1

¿Fue útil?

Solución

El problema puede ser resuelto simplemente especificando el comienzo y el final índices para unpack() y utilizando el table.maxn() como el índice de fin:

table1 = {true, nil, true, false, nil, true, nil}

a1,b1,c1,d1,e1,f1,g1 = unpack( table1, 1, table.maxn(table1) )
print ("table1:",a1,b1,c1,d1,e1,f1,g1)
-->table1: true    nil     true    false   nil     true    nil

La verdadera razón de la discrepancia en cómo se manejan las dos tablas es en la lógica de determinación de la longitud de la parte de la matriz de la mesa.

La función luaB_unpack() utiliza luaL_getn() que se define en términos de lua_objlen() que exige luaH_getn() para las tablas. El luaH_getn() se ve en la última posición de la matriz, y si es nil realiza una búsqueda binaria para un límite en la tabla ( "tal que t [i] no es nil y t [i + 1] es nula"). La búsqueda binaria para el final de la matriz es la razón por la que table1 se maneja de forma diferente a continuación, table2.

Esto sólo debería ser un problema si la última entrada en la matriz es nil.

De Programación rel="noreferrer"> (pg.16) (debe comprar este libro).: Cuando una matriz tiene agujeros - nil elementos dentro de ella - el operador longitud puede asumir cualquiera de estos elementos nil como el marcador de final. Por lo tanto, se debe evitar el uso del operador de longitud en matrices que pueden contener agujeros.

El unpack() está utilizando el lua_objlen() operador longitud, que "puede asumir cualquiera de [la] nil elementos como el final" de la matriz.

Otros consejos

2.2 - Valores y Tipos

  

[...]   El tipo tabla implementa asociativo   matrices, es decir, matrices que pueden ser   indexados no sólo con números, pero   con cualquier valor (excepto nil). Mesas   puede ser heterogéneo; es decir, que    puede contener valores de todos los tipos   (Excepto nil) . [...]

Dado nil a una entrada será romper la enumeración mesa y sus variables no será init correctamente.

Aquí está un ejemplo sencillo que demuestra un problemática comportamiento:

table1 = {true, false, nil, false, nil, true, nil}
for k,v in ipairs(table1) do
  print(k, v)
end

salida:

1   true
2   false
>Exit code: 0
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top