直接回答:引用透明指一个表达式可以被它的求值结果直接替换而不改变程序行为。成立的前提有二:同样的输入永远得到同样的输出(确定性),且求值过程没有副作用。它是纯函数的核心性质。
示例:
# 引用透明:结果只取决于参数,无副作用
def add(a, b):
return a + b
total = 0
# 引用不透明:修改外部状态(副作用)
def add_to_total(x):
global total
total += x
return total
# 同样不透明:结果依赖外部可变状态,两次调用结果可能不同
import random
def roll():
return random.randint(1, 6)
add(2, 3) 在程序任何地方换成 5 都无所谓;而 add_to_total(2) 换成它的返回值后,程序后续行为就变了。
展开解析:引用透明带来的工程价值——
- 可推理:理解一个函数只需看它的参数,不用追溯全局状态;
- 可缓存:相同输入可直接复用结果(memoization 的安全前提);
- 可并行:纯函数无共享状态,随意并发执行;
- 易测试:不用搭建环境,断言输入输出即可。
易错点:打印日志、写文件、抛异常都算副作用;把可变对象当参数并在函数内修改它同样破坏透明性。追问:副作用该放到哪里(函数式架构中推到系统边界,如 IO Monad 的思想)。