副作用 (計算機科學)
編輯在計算機科學中,如果一個操作、函數或表達式在其局部環境之外修改了某些狀態變量值,則稱其具有副作用,也就是說,除了返回 a 的主要效果之外,它是否具有任何可觀察到的效果 值給操作的調用者。 示例副作用包括修改非局部變量、修改靜態局部變量、修改通過引用傳遞的可變參數、執行 I/O 或調用其他具有副作用的函數。 在存在副作用的情況下,程序的行為可能取決于歷史; 也就是說,評估的順序很重要。 理解和調試具有副作用的函數需要了解上下文及其可能的歷史。
副作用在編程語言的設計和分析中起著重要作用。 使用副作用的程度取決于編程范例。 例如,命令式編程通常用于產生副作用、更新系統狀態。 相比之下,聲明式編程通常用于報告系統狀態,沒有副作用。
函數式編程旨在最小化或消除副作用。 沒有副作用使得對程序進行形式驗證變得更加容易。 函數式語言 Haskell 通過將它們替換為 monadic 操作來消除 I/O 和其他有狀態計算等副作用。 StANDard ML、Scheme 和 Scala 等函數式語言不限制副作用,但程序員習慣于避免它們。
匯編語言程序員必須意識到隱藏的副作用——修改指令助記符中未提及的處理器狀態部分的指令。 隱藏副作用的一個典型示例是一條算術指令,它隱式修改條件代碼(隱藏副作用),同時顯式修改寄存器(預期效果)。 具有隱藏副作用的指令集的一個潛在缺點是,如果許多指令對單個狀態(如條件代碼)有副作用,則按順序更新該狀態所需的邏輯可能成為性能瓶頸。 這個問題在一些設計有流水線(自 1990 年)或無序執行的處理器上尤為嚴重。 這樣的處理器可能需要額外的控制電路來檢測隱藏的副作用并在下一條指令取決于這些影響的結果時停止流水線。
引用透明
編輯沒有副作用是引用透明的必要條件,但不是充分條件。 引用透明意味著表達式(例如函數調用)可以用它的值替換。 這要求表達式是純的,也就是說表達式必須是確定性的(總是對相同的輸入給出相同的值)并且沒有副作用。
暫時的副作用
編輯在討論副作用和引用透明性時,通常會忽略由操作執行所花費的時間引起的副作用。 在某些情況下,例如硬件時序或測試,會專門針對其暫時的副作用插入操作,例如 sLeep(5000) 或 for (int i = 0; i < 10000; ++i) {}。 除了需要一定的時間才能完成之外,這些指令不會改變狀態。
冪等性
編輯如果子例程的多個應用程序對系統狀態的影響與單個應用程序相同,則具有副作用的子例程是冪等的,換句話說,如果從系統狀態空間到自身與子例程相關聯的函數在數學意義上是冪等的。
setx 是冪等的,因為第二次將 setx 設置為 3 對系統狀態的影響與第一次應用相同:x 在第一次應用后已設置為 3,在第二次應用后仍設置為 3。
如果純函數在數學意義上是冪等的,則它是冪等的。 例如,考慮以下 Python 程序:
def abs(n): 如果 n < 則返回 -n 0 else nassert abs(abs(-3)) == abs(-3)
abs 是冪等的,因為第二次應用 abs 到第一次應用到 -3 的返回值與第一次應用到 -3 返回相同的值。
例子
編輯副作用行為的一個常見演示是 C 中的賦值運算符。賦值 a = b 是一個計算結果與表達式 b 相同的值的表達式,具有將 b 的 R 值存儲到 L 中的副作用 -a 的值。 這允許多重分配:
一 = (b = 3); // b = 3 計算結果為 3,然后將其分配給 a
因為運算符關聯,這相當于
一 = b = 3;
這對新手程序員來說是一個潛在的障礙,他們可能會混淆
while (b == 3) {} // 測試 b 是否等于 3
內容由匿名用戶提供,本內容不代表www.gelinmeiz.com立場,內容投訴舉報請聯系www.gelinmeiz.com客服。如若轉載,請注明出處:http://www.gelinmeiz.com/195617/