Skip to content

Latest commit

 

History

History
63 lines (57 loc) · 2.82 KB

0X25表嵌套.md

File metadata and controls

63 lines (57 loc) · 2.82 KB

0X25 表嵌套

前置知识

  • 0X24 词典

正文

  1. 表也可以作为表的成员.如果表的成员本身也是表,就可能出现连续使用多个方括号多次索引.例如:
    L1={'hello','world','good'}
    L2={23,34,L1}
    print(L2[3][2])
    在输出时,L2先和[3]结合.返回值是L1的值.它仍是一个表,继续和[2]结合.返回的值就是'world'.
  2. 一个表也可以是自己的成员,由于定义这个表的时候它本身的变量名还没有被赋值.所以把自己变成自己的成员这个过程需要一个中间步骤.
    L={12,34}
    L[3]=L
    print(L[3][3][1])
    L[3][3][3]==L
  3. 如果不涉及自我包含.表的嵌套可以一次性定义出来.
    L={12,34,{222,333,3334},83}
    print(L[3][1])
  4. 特别注意.在表作为表的成员时.并没有把作为成员的表复制一份.而是只保存了一个引用.(这很好理解,如果一个表作为另一个表的成员就复制一份的话.一个包含自己的表会瞬间耗尽任意大的内存.)
  5. 关于6中提到的问题.更正式的说法是Lua中的表是引用类型.这涉及内存分配的问题.我不想在此展开讨论.如果你已经了解过引用类型和值类型的区别.那么在Lua中,把所有类型都当做引用类型处理就行了.因为把值类型当作对常量的引用就好了.
  6. 引用类型的一个很直观的体现就是,在修改作为成员的表的内容的时候.如果通过把这个表当作成员的表访问,查看到的也是修改后的结果.例如:
    L1={3,4,5}
    L2={8,L1,9}
    print(L2[2][1])
    L1[1]='I  am changed'
    print(L2[2][1])
  7. 那么如果我希望得到一个链表的复制品(修改一个时候不会影响另一个).就需要创建一个新的表,然后把前者的数据都复制过来.例如:
    LL1={4,5,6}
    LL2={}
    LL2[1],LL2[2],LL2[3]=LL1[1],LL1[2],LL1[3]
    print(LL2[1],LL2[2],LL2[3])
    LL1[2]='Changed'
    print(LL1[2])
    print(LL2[2])
  8. 在9中举例的方法.如果结合了结构控制中的循环语句 .就能实现对任意成员个数的表实现复制.但是这还是没有办法解决嵌套表的复制问题.例如:
    L={1,2,3}
    L1={8,L}
    L2={}
    L2[1],L2[2]=L1[1],L1[2]
    L1[2][3]='Changed'
    print(L1[2][3])
    print(L2[2][3])
    可以看到L1和L2中的第二个元素的第三个元素同时被改变了.或者更准确地说是,这两个元素其实是同一个元素.
  9. 解决嵌套表的复制问题.可以结合值类型判断使用递归算法.在复制一个表时如果它的成员仍旧是表,则对这个成员也递归使用复制函数.不过这些算法层面的问题和具体的语言关系不大,我将在别的教程中详细讨论.

后续推荐

  • 0X2C 表的遍历