直接回答:NLL(Non-Lexical Lifetimes,2018 起默认)把借用生命周期的判定从"作用域结束才过期"改为"最后一次使用之后就过期"。借用不再跟着花括号走,而是跟实际控制流走:只要最后一次使用之后没有再读,编译器就认为借用已死,允许新的可变借用或 move。这让大量"明明安全却被拒"的代码通过编译,写法和直觉对齐。
展开解析:经典例子:先 let r = &mut v; 用完后不再碰 r,接着 v.push(...)——旧版报错借用冲突,NLL 下 r 的借用在最后一次使用后即结束,合法。再如从 HashMap 查找后分支:找到则返回引用、找不到则 insert——曾经需要 match 嵌套绕开,NLL 加 Polonius 思路让直白写法通过(当前版本对这类 case 仍有边界,entry API 仍是稳妥写法)。要点是 NLL 没有改变规则本身,只是让生命周期推断更精确:互斥原则(同域内不共存可变与不可变借用)依旧,悬垂依旧被拒。遇到借用错误时的排查顺序:缩短借用存活范围、拆分函数、改返回拥有值、必要时用索引替代引用。
追问方向:Polonius 要解决 NLL 的哪些剩余假阴性?为什么闭包捕获与环境借用常起冲突?双文件互借的结构体字段(拆分借用)怎么工作?
(约 440 字)