注意:我标记了这个 Python 和 C++,因为我已经看到了这两个例子,但问题是与语言无关。
修改对象的函数或类方法有两种选择:直接修改相关对象中的数据,或者创建一个新副本并返回它,同时保持原始数据不变。通常,您可以通过查看函数返回的内容来判断哪个是哪个。
有时您会发现一个函数尝试同时执行这两种操作,修改原始对象,然后返回对该对象的副本或引用。有没有这样的情况比只做一个或另一个提供任何优势?
我已经看到了依赖于返回对对象的引用的流畅接口或方法链的示例,但这似乎是一种特殊情况,在上下文中应该是显而易见的。
我的第一个不好的例子直接来自Python 文档,并说明了可变默认参数的问题。对我来说,这个例子是不切实际的:如果函数修改了它的参数,那么有一个默认值是没有意义的,如果它返回一个副本,那么应该在任何修改发生之前制作副本。问题之所以存在,是因为它试图两者兼而有之。
def f(a, L=[]):
L.append(a)
return L
第二个示例来自CStringT::MakeUpper
函数中的 Microsoft C++。文档说明了返回值:
返回字符串的副本,但全部为大写字符。
这导致人们期望原件保持不变。部分问题在于文档具有误导性,如果您查看原型,您会发现它返回了对字符串的引用。除非仔细观察,否则您不会注意到这一点,并且将结果分配给新字符串编译不会出错。惊喜在后面。