拆穿魔法师的把戏:编译器在背后施展的“状态机“魔法
引子:小明的"不服气"上一篇文章的结尾,小明终于学会了用协程,还知道了那句关键的话——“协程能暂停续播,是因为编译器在背后把它变成了一个’状态机’”。他一度心满意足。可几天后,一种"知其然而不知其所以然"的不服气,又在他心里冒了出来:"‘编译器把它变成状态机’——这句话说得轻巧,可到底是怎么变的?一个普普通通的函数,一个while循环,一句yield return null——它凭什么就能’暂停’?函数不是一旦调用就该一口气跑到底、然后彻底结束吗?它’暂停’的那一刻,人跑哪去了?那些局部变量,又藏在了哪里?下一帧它’醒来’,又是怎么精准地知道’我上次停在了第几行’的?这背后,一定有一套具体的、看得见摸得着的’机关’。我不信这是什么无法理解的黑魔法!"小明的这份"不服气",恰恰是一个程序员走向成熟的标志——不满足于"会用",而要追问"为什么"。好,那今天,我们就来做一件"拆穿魔法"的事。我们要走到那位"时间魔法师"(协程)的幕后,一把揭开它的斗篷,看看编译器这位真正的"魔术师",到底施展了怎样的"状态机"魔法——把一个看似不可能"暂停"的普通函数,改造成了一个能够随意暂停、续播、还记得住一切的神奇机器。准备好了吗?我们要拆穿这个把戏了。你会发现,所谓魔法,拆穿之后,是一套精妙绝伦、却又清清楚楚、逻辑严密的机械设计。