干净的代码:很少参数的函数[关闭]


48

我读过罗伯特·C·马丁(Robert C. Martin)的“ 清洁代码”的第一章,在我看来,这很不错,但是我怀疑,在某种程度上,有人提到函数应该具有尽可能少的参数是很有意义的(认知上)甚至可能暗示3个或更多参数对于一个函数来说太过昂贵了(我发现它非常夸张和理想化),所以我开始怀疑...

使用全局变量和在函数上传递许多参数的实践都是不好的编程习惯,但是使用全局变量可以大大减少函数中参数的数量。

所以我想听听您对此的看法,使用全局变量减少函数参数的数量是否值得?在什么情况下会呢?

我认为这取决于几个因素:

  • 源代码大小。
  • 平均功能参数数。
  • 功能数量。
  • 使用相同变量的频率。

我认为,如果源代码的大小相对较小(例如少于600行代码),则有许多函数,将相同的变量作为参数传递,并且这些函数具有许多参数,那么使用全局变量将是值得的,但是我想知道...

  • 你有我的看法吗?
  • 您对源代码较大的其他情况有什么看法?

PS。我看到了这篇文章,标题非常相似,但是他没有问我想知道什么。


144
我认为替代方案不是全局变量,而是将参数合并到对象中。可能更多是关于postLetter(string country, string town, string postcode, string streetAddress, int appartmentNumber, string careOf)的臭味的建议postLetter(Address address)。继续阅读这本书,希望它能说出类似的话。
内森·库珀

3
@DocBrown我想问的意思是更像Bob叔叔说的不使用3个以上的参数,所以我通过使用全局变量来解决这个问题,对吗?:-)我认为可能的作者并不知道有解决此问题的更好方法-如以下答案中所述。
bytedev '17

9
根据经验,对于n的任何值,最多不超过n个参数,而不是将其蚀刻在钻石上。不要将好的建议误认为一项授权。通常,许多参数是一种代码异味,您在一个函数/方法中进行了太多操作。人们过去常常避免拆分成多个功能,以躲避额外调用的额外开销。很少有应用程序需要这种性能密集型应用程序,分析器可以告诉您何时何地需要避免额外的呼叫。
加里德·史密斯

14
这说明了这种无判断力的规则有什么问题:它为无判断力的“解决方案”打开了大门。如果一个函数有很多参数,则可能表明它不是次优的设计,通常不仅是该函数的设计,还包括它在其中使用的上下文。解决方案(如果需要的话)是寻求重构代码。我不能给您一个简单的,通用的,不受评判的规则,但这并不意味着“不超过N个论点”是个好规则。
sdenham

4
如果函数的参数太多,则其中的一些可能性是相关的,应将其分组为一个对象,然后该对象成为封装多个数据的单个参数。这里有第三种选择。

Answers:


113

我不同意你的看法。在我看来,不管您描述的质量如何,使用全局变量比使用更多参数都更糟糕。我的理由是,更多的参数可能会使方法更难以理解,但是全局变量可能会导致代码出现许多问题,包括可测试性差,并发错误和紧密耦合。无论一个函数有多少个参数,它固有的问题都不会与全局变量相同。

...将相同的变量作为参数传递

可能是设计气味。如果将相同的参数传递给系统中的大多数功能,则可能存在跨领域问题,应通过引入新组件来解决。我认为将相同的变量传递给许多函数并不是引入全局变量的合理理由。

在对问题的一次编辑中,您指出引入全局变量可能会提高代码的可读性。我不同意。全局变量的用法隐藏在实现代码中,而函数参数在签名中声明。理想情况下,功能应该是纯函数。它们仅应根据其参数进行操作,并且不应有任何副作用。如果您具有纯函数,则可以仅查看一个函数就可以对该函数进行推理。如果您的函数不是纯函数,则必须考虑其他组件的状态,这将使推理变得更加困难。


好吧,很高兴听到其他意见,但是关于设计气味,我正在用人工智能方法解决的C问题中编程,而且我倾向于使用许多几乎总是使用相同矩阵,数组或变量的函数(我将参数作为参数传递给函数),之所以这样说,是因为我不觉得我可以将这些变量放在结构或联合之类的通用概念/事物之内,所以我不知道如何进行更好的设计,因此,这就是为什么我认为在这种情况下使用全局变量可能是值得的,但很可能我是错的。
OiciTrap

1
这听起来不像是设计问题。我仍然认为将参数传递给函数是最好的设计。在您正在描述的AI系统中,我会发现编写单元测试来测试系统的各个部分非常有用,而最简单的方法就是使用参数。
塞缪尔

96
更多的参数使子程序更难以理解,全局变量使整个程序难以理解,即所有子程序均难以理解。
约尔格W¯¯米塔格

2
我维护一个代码库,其中的某些函数使用了十几个参数。这是一个巨大的时间浪费-每次我需要调用该函数时,都需要在另一个窗口中打开该文件,以便知道需要按什么顺序指定参数。如果我使用的IDE给我提供了类似于Intellisense的信息,或者如果我使用的是一种命名参数的语言,那还不错,但是谁能记住所有这些功能的十二个参数的顺序呢?
杰里·耶利米

6
答案是正确的,尽管如此,似乎OP还是对“清洁代码”中的建议有误解。我敢肯定,在那本书中没有建议用全局变量代替函数参数。
布朗

68

您应该避免像瘟疫这样的全局变量。

我不会对参数的数量(例如3或4)施加硬性限制,但是如果可能的话,您确实希望将其数量减至最少。

使用structs(或C ++中的对象)将变量组合在一起成为单个实体,并将其(通过引用)传递给函数。通常,函数会获得传递给它的结构或对象(其中包含一些不同的东西)以及一些其他参数,这些参数告诉函数对该函数执行某些操作struct

对于气味良好,简洁的模块化代码,请尝试遵循单一责任原则。使用您的结构(或对象),函数和源文件执行此操作。如果这样做,传递给函数的参数的自然数量将显而易见。


5
传递隐藏在结构中的数十个参数与显式传递它们之间的主要区别是什么?
Ruslan

21
@Ruslan凝聚力。
abuzittin gillifirca '17

9
而且您更有可能将功能重构为较小的功能,因为您可以将一个参数传递给子功能,而不是传递数十个参数。如果使用位置参数,混合参数的风险也较小。
汉斯·奥尔森

8
很好,但是您必须确保Structs中的一致性-确保分组到Struct中的参数是“相关的”。在某些情况下,您可能会使用多个Struct。
安德鲁·多德斯

8
@abuzittingillifirca您不会自动获得凝聚力。如果将参数放入结构的唯一理由是将参数传递给特定函数,那么内聚可能只是虚幻的。
sdenham

55

我们在谈论认知负荷,而不是语法。所以问题是... 在这种情况下什么参数?

参数是影响函数行为的值。参数越多,获得的值组合就越可能,关于函数的推理就越难。

从这个意义上说,函数使用的全局变量参数。它们是没有出现在签名中的参数,具有构造顺序,访问控制和剩余性问题。

除非所说的参数是所谓的横切关注点,即所有程序都在使用的程序状态,但没有任何改变(例如,日志记录对象),否则不应将函数参数替换为全局变量。它们仍然是参数,但是更糟糕。


11
对于您+1,无论是厕所还是马桶,它们都一样。指出披着羊皮的狼的工作真好。
贾里德·史密斯

1
+1表示许多参数和全局变量都不好。但我想澄清一下。在大多数语言中,默认情况下按值传递原始参数(Java),而在其他语言中,可以按值显式传递它们(PL / SQL)。另一方面,全局原语总是通过引用来访问(可以这么说)。因此,至少是原始类型的参数始终比全局变量更安全。尽管具有两个或三个以上参数当然是一种气味,而具有十二个参数则是一种巨大的气味,应该重构。
图兰斯·科尔多瓦

4
绝对,全局变量是一个隐藏参数。
Bill K

+1到您的观点,我已经看到了依赖全局变量传递数据的MATLAB仿真。结果是完全不可读的,因为很难分辨哪个变量是哪个函数的参数。
Cort Ammon

34

恕我直言,您的问题是基于一种误解。在“ Clean Code”中,Bob Martin不建议用全局变量代替重复的函数参数,这是一个非常糟糕的建议。他建议将其替换为该函数类的私有成员变量。而且他还提出了小的,有凝聚力的类(通常小于您提到的600行代码),因此这些成员变量绝对不是全局变量。

因此,当您在少于600行的上下文中有意见时,“使用全局变量将是值得的”,那么您将完全赞同Bob叔叔的意见。当然,“最大3个参数”是否是理想数是有争议的,并且即使在小类中,该规则有时也会导致太多成员变量。恕我直言,这是一个折衷,没有严格的规则来划清界限。


10
我从来不明白为什么有人会喜欢通过将参数填充到构造函数中而不是仅仅使用实际参数来使类具有状态。这总是令我震惊,因为它的复杂性大大增加。(我见过的一个真实的例子是一个数据库连接对象,当与依赖注入结合使用时,它使尝试通过程序跟踪数据库的状态变得几乎不可能。)但是也许Clean Code对此有更多的话要说。学科。当然,在使事情变得有状态时,全局变量是一个更差的选择。
jpmc26

2
@ jpmc26:如果类变得太大且成员变量太多,则只会“极大地增加复杂性”,因此结果不再具有内聚性。
布朗

4
我认为响应忽略了分散在许多类中的状态管理(甚至可能是可变的)的困难。当函数不仅取决于参数,还取决于对象的构造方式(甚至在生命周期内进行了修改)时,在进行特定调用时了解其当前状态会变得更加困难。现在,您必须跟踪另一个对象的构造,才能弄清楚调用将执行的操作。除非您构造对象并立即将其丢弃,否则添加实例变量会主动增加程序的状态量?
jpmc26

3
@ jpmc26重构时我经常使用的一种模式是构造函数的行为就像设置上下文一样,然后方法参数特定于操作。对象不是完全有状态的,因为它所持有的状态永远不会改变,但是将这些通用动作移入该容器的方法中可以显着提高使用该对象的可读性(仅设置一次上下文,类似于python的上下文管理器),并在出现以下情况时减少重复对对象的方法进行了多次调用。
伊兹卡塔

3
+1明确表示成员变量不是全局变量。许多人认为他们是。
图兰斯·科尔多瓦

34

拥有许多参数被认为是不可取的,但是将它们转换为字段或全局变量则要糟糕得多,因为它不能解决实际问题,但会引入新问题。

具有许多参数本身并不是问题,但这是您可能有问题的征兆。考虑以下方法:

Graphics.PaintRectangle(left, top, length, height, red, green, blue, transparency);

具有7个参数是明确的警告信号。潜在的问题是这些参数不是独立的而是成组的。lefttop属于在一起作为Position-结构,lengthheight作为一个Size结构,并且redbluegreen作为一个Color结构。也许Color透明度属于Brush结构?也许Position并且Size属于一个Rectangle结构,在这种情况下,我们甚至可以考虑将其变成对象Paint上的方法Rectangle?因此,我们可能最终得到:

Rectangle.Paint(brush);

任务完成!但是重要的是,我们实际上已经改善了总体设计,并且减少了参数数量是其结果。如果仅减少参数数量而不解决潜在问题,则可能会执行以下操作:

Graphics.left = something;
Graphics.top = something;
Graphics.length = something;
...etc
Graphics.PaintRectangle();

在这里,我们实现了相同数量的参数减少,但是实际上使设计变得更糟

底线:对于任何编程建议和经验法则,了解潜在的推理非常重要。


4
+1好的,建设性的,可理解的,非理论性的答案。
AnoE

1
更不用说,具有长度和高度属性的“正方形”到底在干什么。:)
通配符

1
+1表示承认某些答案(即,在函数调用之前对某些结构/对象的许多分配)所暗示的明显第三种方式并没有更好的效果。
benxyzzy

@Wildcard:谢谢,将其更改为“矩形”以避免混淆该问题!
JacquesB

7

是否值得使用全局变量来减少函数的参数数量?

我读了本书的第一章

您读了本书的其余部分吗?

全局只是一个隐藏的参数。它们引起另一种痛苦。但这仍然很痛苦。不要再想办法解决这个规则了。考虑如何遵循它。

什么是参数?

是东西 在贴有标签的框中。当您可以在其中放入任何东西时,为什么有多少个盒子很重要?

这是运输和处理的成本。

Move(1, 2, 3, 4)

告诉我你可以读懂。继续尝试。

Move(PointA, PointB)

这就是为什么。

该技巧称为“ 引入参数对象”

是的,如果您要做的只是计数参数,那只是一个技巧。您应该计算的是IDEAS!抽象!你让我立刻考虑多少?把事情简单化。

现在这是相同的计数:

Move(xyx, y)

哇!那太糟了!这里出了什么问题?

仅仅限制想法的数量是不够的。他们必须是明确的想法。什么是xyx?

现在,这仍然很薄弱。有什么更强大的方式考虑这一点?

功能应该很小。不小于那个。

鲍伯叔叔

Move(PointB)

为什么要使该功能执行超出其实际需要的工作?单一责任原则不仅适用于班级。认真地说,有必要更改整个体系结构,以阻止一个功能变成具有10个有时相关参数的过载梦night,其中一些参数不能与其他参数一起使用。

我看过一个函数中最常见的行数为1的代码。我并不是说您必须这样写,但要保留,别告诉我,全球性是您可以遵守此规则的唯一方法。停止尝试摆脱重构该功能的麻烦。你知道可以的。它可能分解为几个功能。它实际上可能变成一些对象。地狱,您甚至可能会将其分解成一个完全不同的应用程序。

这本书并没有告诉您要计算参数。告诉您要注意造成的痛苦。任何解决痛苦的方法都可以解决问题。当您只是在用一种痛苦换另一种痛苦时,请注意。


3
“你读了本书的其余部分吗?” 我的帖子的前8个字回答了您的问题……
OiciTrap

我完全同意-关键是将问题分解成小块。对象确实可以帮助组织这些片段并将它们分组,它们还允许将单个概念单元作为参数传递,而不是一堆未连接的片段。当我看到一个带有3个以上参数的方法时,我会感到不安。5表示我的设计已经停滞不前了,我需要另一轮重构。我发现解决诸如参数计数之类的设计问题的最好方法是将事物重构为更小,更简单的单元(类/方法)。
Bill K

2
这个答案的语气可以改善。它读起来非常突然而刺耳。例如:“告诉我,您可以阅读。继续,尝试。” 看起来非常激进,可以重写为“上面/下面的两个函数调用中,哪个更容易阅读?” 您应该尝试在没有侵略性的情况下理解问题。OP只是在尝试学习。
Kyle A

不要忘记OP也试图保持清醒状态。
candied_orange

4

我永远不会使用全局变量来减少参数。原因是全局变量可以由任何函数/命令更改,因此使函数输入不可靠,并且容易出现超出函数可处理范围的值。如果在函数执行期间更改了变量,并且函数的一半与另一半具有不同的值,该怎么办?

另一方面,传递参数将变量的范围限制为仅其自身的函数,这样,一旦函数被调用,则只有函数才能修改参数。

如果您需要传递全局变量而不是参数,则最好重新设计代码。

只是我的两分钱。


完全同意“我永远不会使用全局变量来减少参数”。它产生不必要的耦合。
bytedev '17

2

我和Bob叔叔在一起,并同意避免使用3个以上的参数(我很少在一个函数中使用3个以上的参数)。单个函数具有很多参数会带来更大的维护问题,并且可能是您的函数执行过多/承担过多职责的气味。

如果您在一种面向对象的语言方法中使用了3个以上的对象,那么您应该考虑这些参数是否在某种程度上彼此不相关,因此您实际上应该传递一个对象吗?

另外,如果您创建更多(较小)的函数,您还会注意到函数往往具有3个或更少的参数。提取功能/方法是您的朋友:-)。

不要使用全局变量来获取更多参数!那就是将一种不好的习惯换成更糟的一种!


1

许多功能参数的有效替代方法是引入参数对象。如果您有一个组合的方法(几乎)将其所有参数传递给其他方法,这将很有用。

在简单的情况下,这是一个简单的DTO,仅保留旧参数作为属性。


1

使用全局变量总是看起来很容易编码(尤其是在一个小程序中),但是这会使您的代码难以扩展。

是的,您可以通过使用数组将参数绑定到一个实体中来减少函数中参数的数量。

function <functionname>(var1,var2,var3,var4.....var(n)){}

上面的函数将被编辑并更改为[使用关联数组]-

data=array(var1->var1,
           var2->var2
           var3->var3..
           .....
           ); // data is an associative array

function <functionname>(data)

我同意robert bristow-johnson的回答:您甚至可以使用结构将数据绑定到单个实体中。


1

以PHP 4为例,查看以下函数的签名mktime()

  • int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )

你不觉得那令人困惑吗?该函数称为“ make time”,但它需要使用日,月和年参数以及三个时间参数。记住他们要执行的顺序有多容易?如果看到了mktime(1, 2, 3, 4, 5, 2246);怎么办?您能理解而不必参考其他内容吗?被2246解释为24小时制的“ 22:46”?其他参数是什么意思?作为一个对象会更好。

转到PHP 5,现在有一个DateTime对象。其方法中有两个称为setDate()setTime()。它们的签名如下:

  • public DateTime setDate ( int $year , int $month , int $day )
  • public DateTime setTime ( int $hour , int $minute [, int $second = 0 ] )

您仍然必须记住,参数的顺序从最大到最小,但是这是一个很大的改进。请注意,没有一个方法可以一次设置所有六个参数。您必须进行两个单独的调用才能执行此操作。

鲍伯叔叔在谈论的是避免使用扁平结构。相关的参数应该组合到一个对象中,如果您有三个以上的参数,则很可能在其中有一个伪对象,这使您有机会创建适当的对象以实现更大的分离。虽然PHP不具有单独的DateTime类,你可以认为DateTime确实包含Date对象和Time对象。

您可能具有以下结构:

<?php
$my_date = new Date;
$my_date->setDay(5);
$my_date->setMonth(4);
$my_date->setYear(2246);

$my_time = new Time;
$my_time->setHour(1);
$my_time->setMinute(2);
$my_time->setSecond(3);

$my_date_time = new DateTime;
$my_date_time->setTime($my_time);
$my_date_time->setDate($my_date);
?>

是否必须每次设置两个或三个参数?如果您只想更改小时或日期,现在很容易做到。是的,需要验证对象以确保每个参数都能与其他参数一起使用,但是无论如何都是如此。

最重要的是,它是否易于理解并因此得以维护?底部的代码块比单个mktime()函数大,但是我认为这更容易理解。即使是非程序员,也不会很费力地确定其功能。目标并不总是较短的代码或更聪明的代码,而是更具可维护性的代码。

哦,不要使用全局变量!


1

这里有很多好的答案,但大多数都没有解决这个问题。为什么有这些经验法则?它与范围有关,与依赖关系有关,并且与适当的建模有关。

用于参数的全局变量更糟,因为它看起来好像只是使它更简单,但实际上您只是隐藏了复杂性。您不会再在原型中看到它,但是您仍然必须意识到它(这很难,因为它不再存在,您无法再看到它了),而绕开函数的逻辑也无济于事,因为可能是其他隐藏在背后的逻辑。您的作用域无处不在,您引入了对任何内容的依赖,因为任何内容现在都可能与您的变量混淆。不好。

要维护一个函数的主要内容是,您可以通过查看原型和调用来了解其功能。因此,该名称应清晰明确。但是,争论越多,就越难把握它的作用。它扩大了您的思维范围,发生了太多的事情,这就是为什么要限制数量。重要的是您要处理的是哪种参数,有些参数比其他参数差。一个额外的可选布尔值(允许不区分大小写的处理)不会使函数难以理解,因此您不希望对其进行过多处理。附带说明一下,枚举比布尔枚举更好,因为枚举的含义在调用中很明显。

典型的麻烦不是您编写了带有大量参数的新函数,而当您还没有意识到要解决的问题到底有多复杂时,您将只从少数几个开始。随着程序的发展,参数列表会逐渐变长。一旦确定了模型,您就想保留它,因为它是您知道的安全参考。但是回想起来,该模型可能没有那么好。您在逻辑上错过了一个步骤,或者您也错过了一个或两个实体。“好吧...我可以重新开始,花一两天的时间来重构我的代码,或者...我可以添加此参数,这样我就可以使它做正确的事情并完成它。现在。对于这种情况为了解决这个问题,我可以将粘滞便笺完成。”

您使用第二种解决方案的次数越多,进一步维护的成本就越高,重构将变得越困难且越没有吸引力。

没有减少现有函数中参数数量的样板解决方案。仅仅将它们组合成化合物并不能真正使事情变得容易,它只是消除复杂性的另一种方法。正确执行此操作涉及再次查看整个调用堆栈,并识别丢失或执行错误的内容。


0

几次我发现将许多一起发送的参数组合在一起可以改善性能。

  • 它迫使您为这些一起使用的概念集锦。如果将这些参数一起使用,则可能是它们之间存在关系(或者根本不应该一起使用)。

  • 一旦有了这个对象,我通常会发现这个看上去很顽固的对象可以移动一些功能。它通常易于测试,并且具有强大的内聚力和低耦合度,因此性能甚至更好。

  • 下次我需要添加新参数时,可以在不更改很多方法签名的情况下添加它。

因此,它可能无法100%地工作,但是请问自己是否应将此参数列表分组到一个对象中。拜托了 不要使用诸如Tuple之类的无类型类,以避免创建对象。您正在使用面向对象的编程,如果需要,不要介意创建更多的对象。


0

出于所有应有的尊重,我很确定您完全错过了在函数中使用少量参数这一点。

这个想法是,大脑一次只能容纳这么多的“活动信息”,如果函数中有n个参数,那么您的大脑中就需要n个以上的“活动信息”,以便轻松,准确地进行操作。理解代码的作用(Steve McConnell,在《 Code Complete》(一本好得多的书,IMO)中)对方法主体中的7个变量说了类似的话:我们很少达到这个目的,但更多的话,您就失去了能力让一切都直达头脑)。

变量数量少的目的是能够使使用此代码的认知需求保持较小,因此您可以更有效地进行处理(或阅读)。这样做的一个附带原因是,良好分解的代码将趋向于具有越来越少的参数(例如,分解不好的代码趋于将一堆东西归为一团)。

通过传递对象而不是值,也许您可​​以获得大脑的某种抽象水平,因为现在它需要实现,我在这里可以使用SearchContext而不是考虑该搜索上下文中可能存在的15个属性。

通过尝试使用Global变量,您完全朝错误的方向发展。现在,您不仅没有解决函数中有太多参数的问题,还解决了这个问题,并将其扔进了一个好得多的好问题中,您现在必须记住!

现在,您不仅要在功能级别上工作,还需要考虑项目的全局范围(糟糕,太糟糕了!我发抖...)。在该函数中,甚至什至没有您所有的信息(废话,那个全局变量名是什么?)(我希望自从我调用此函数以来,这没有被其他更改)。

全局范围的变量是项目(无论大小)中最糟糕的事情之一。它们表示无法进行适当的范围管理,这是编程的一项基本技能。他们。是。邪恶。

通过将参数移出函数并将其放到全局变量中,您已经陷入了困境(或者腿或脸)。上帝禁止你决定,嘿,我可以将这个全局性用于其他用途……我的思想在为这个想法而颤抖。

整个理想是使事情易于管理,而全局变量不会做到这一点。我要说的是,它们是朝相反方向前进时最糟糕的事情之一。


-1

我发现了一种非常有效的方法(在JavaScript中),以最小化接口之间的摩擦:对所有模块使用统一的接口,特别是:单个参数函数。

当您需要多个参数时:使用单个对象/哈希或数组。

忍受我,我保证我不会拖钓...

在您说“单个参数函数有什么用?”或“ 1数组函数和多参数函数之间有区别吗?”之前,

嗯,是。从视觉上看可能很细微,但是区别却是多方面的- 我在这里探索了许多好处

显然有些人认为3是正确的参数数。有人认为是2。嗯,这仍然引出了一个问题,“ arg [0]中有哪个参数?” 而不是选择用更严格的声明约束接口的选项。

我想我主张一个更激进的立场:不要依赖于立场争论。我只是觉得它很脆弱,并且导致了关于该死的论点的论点。跳过它,继续前进,不可避免地要争论函数和变量的名称。😉

认真地说,在命名确定之后,希望您最终得到如下代码,该代码有些自我记录,对位置不敏感,并且允许将来在函数内部处理参数更改:

function sendMessage({toUser, fromUser, subject, body}) { }

// And call the method like so:
sendMessage({toUser: this.parentUser, fromUser: this.currentUser, subject: ‘Example Alert’})


6
伪造命名参数并不是只传递一个参数。
JDługosz

如果我实现了设定的目标,为什么会“伪造”?我将命名参数的优先级提高。因为位置args在调用代码时并不明显,并且使用#命名函数,开发人员必须记住,因此记住哪个参数在哪里以及哪个可选参数是无济于事的。...最终,您将需要在可选件,好运文档和升级纸牌屋之后添加必需的参数。
丹·利维

2
命名的参数也是增强学习的技巧-人类将更多的含义赋予单词集合。
丹·利维
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.