诅咒金字塔 (编程)

计算机编程中，诅咒金字塔（pyramid of doom）是一种常见编码风格——程序用多层嵌套的缩进来访问一个功能。常见于检查空指针或处理回调函数。

例子
大多数现代面向对象编程语言使用点表示法，允许单行代码中的多层方法调用，每一层方法调用用点来分割。例如： 

theWidth = windows("Main").views(5).size().width();
这段代码首先在windows集合中找到一个名字为"Main"的窗体，再找到窗体的views集合中第5个subview，调用其size方法，返回的结构中再调用width方法，结果最后赋值给变量名theWidth。

上述代码存在的问题是需要假定所有这些值都存在。如果这个假设不成立，则会遇到空指针错误。

为避免这类问题，一般在每层方法调用都要检查其返回值。一个更为安全的编码为： 
if windows.contains("Main") {
    if windows("Main").views.contains(5) {
        theWidth = windows("Main").views(5).size().width();
        //more code that works with theWidth
    }
}

如果还想检查值是否存在、是否有效，if语句中的代码就会越来越靠右，使得阅读代码更为困难。一些让代码扁平化的方法被提了出来： 
if windows.contains("Main") { theWindow = windows("Main") }
if theWindow != null && theWindow.views.contains(5) { theView = theWindow.views(5) }
if theView != null {
    theWidth = theView.size().width();
    //additional code
}

或者：
if !windows.contains("Main") {
    // handle error
} else if !windows("Main").views.contains(5) {
    // handle error
} else {
    theWidth = windows("Main").views(5).size().width();
    //more code that works with theWidth
}

很多编程语言为此提供了一些语法糖来解决这类问题。例如Apple的Swift语言在if语句中增加了optional chaining。微软的C# 6.0和Visual Basic 14增加了null-conditional运算符?.和?[分别用于成员访问和下标访问。基本想法是访问空对象的成员时直接返回空值，例如： 
theWidth = windows("Main")?.views(5)?.size.width;
如果"Main"或第五个subview缺失，整个值为空。Swift语言增加了if let语句，即"optional binding":
if let theView = windows("Main")?.views(5) {
    //do things knowing the view exists...
    theWidth = theView.size.width
}

参见
 Promise，一种避免诅咒金字塔的技术，如用于JavaScript
最少知识原则
 安全导航运算符

参考文献

程序架構