• lua报错,看到报错信息有tail call,以为和尾调用有关,于是查了一下相关知识


      尾调用是指在函数return时直接将被调函数的返回值作为调用函数的返回值返回,尾调用在很多语言中都可以被编译器优化, 基本都是直接复用旧的执行栈, 不用再创建新的栈帧, 原理上其实也很简单, 因为尾调用在本质上看的话,是整个子过程调用的最后执行语句, 所以之前的栈帧的内容已经不再需要, 完全可以被复用。报错的回溯日记,因为旧的执行栈已经没了,所以报错日记只显示(tail call)。一般调用栈的长度为1M到2M,保存了调用过程中的参数和相关环境,如果递归调用太长,就会溢出。尾调用就能解决递归函数带来的问题。

      当时我还怀疑了闭包会不会产生溢出的问题。我觉得闭包的upvalue最后会复制一份放在另一块内存,而不会继续放在调用栈内,所以不会导致溢出,最多就是导致内存泄漏。后来发现闭包的upvalue有一个限制,就是同一个闭包内upvalue的数量不能超过255个。

      我所遇到的问题显然和尾调用,闭包都没关系,我再继续看报错日记,最后的日记是 attempt to perform arithmetic on field '?' is a nil value。我晕,on field '?'是啥意思。

      如果: local aa = {y=2,z=3}

          local dd = aa.x + 1

      就会报 attempt to perform arithmetic on field 'x' is a nil value 因为x确实是nil值。那么,'?'代表什么的,后来发现是数组下标出错。

      如果:lcoal test = {1,2,3,4,5}

         lcoal ret = test [9] + 10

      此时就会报 attempt to perform arithmetic on field '?' is a nil value 因为数组越界了。

  • 相关阅读:
    数据库事务之不可重复读
    数据库事务与脏读
    图结构代码实现
    哈希表与散列函数
    数据库表设计与视图
    B树和B+树
    java之字符串中查找字串的常见方法
    剑指 Offer 15. 二进制中1的个数——JS
    剑指 Offer 03. 数组中重复的数字——JS
    算法设计与分析——排序
  • 原文地址:https://www.cnblogs.com/jsfx/p/7475892.html
Copyright © 2020-2023  润新知