默认参数vs重载,何时使用 [英] Default arguments vs overloads, when to use which

查看:117
本文介绍了默认参数vs重载,何时使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Kotlin中,有两种表达可选参数的方式,一种是通过指定默认参数值来实现:

In Kotlin there are two ways to express an optional parameter, either by specifying default argument value:

fun foo(parameter: Any, option: Boolean = false) { ... }

或引入重载:

fun foo(parameter: Any) = foo(parameter, false)
fun foo(parameter: Any, option: Boolean) { ... }

在哪种情况下首选哪种方式?

Which way is preferred in which situations?

这种功能的消费者有什么区别?

What is the difference for consumers of such function?

推荐答案

在Kotlin代码中,调用其他Kotlin代码的可选参数通常是使用重载的规范.使用可选参数应该是您的默认行为.

In Kotlin code calling other Kotlin code optional parameters tend to be the norm over using overloads. Using optional parameters should be you default behavior.

使用默认值的特殊情况:

  • 作为常规做法或不确定(如果不确定,请使用默认参数覆盖替代内容.)

  • As a general practice or if unsure -- use default arguments over overrides.

如果您希望调用者看到默认值,请使用默认值.它们将显示在IDE工具提示(即Intellij IDEA )中,并让调用者知道它们已作为合同的一部分被应用.您可以在下面的屏幕截图中看到,如果xy的值被省略,则调用foo()将默认一些值:

if you want the default value to be seen by the caller, use default values. They will show up in IDE tooltips (i.e. Intellij IDEA) and let the caller know they are being applied as part of the contract. You can see in the following screenshot that calling foo() will default some values if values are omitted for x and y:

使用函数重载来做同样的事情会隐藏这些有用的信息,只会带来更多混乱:

Whereas doing the same thing with function overloads hides this useful information and just presents a much more messy:

使用默认值会导致两个函数的字节码生成,一个具有指定的所有参数,另一个是桥接函数,可以检查和应用缺少的参数及其默认值.无论您有多少个默认参数,它总是两个功能.因此,在总功能数受限制的环境( ie Android )中,最好只拥有这两个功能,而不是完成相同工作所需的大量重载.

using default values causes bytecode generation of two functions, one with all parameters specified and another that is a bridge function that can check and apply missing parameters with their defaulted values. No matter how many defaulted parameters you have, it is always only two functions. So in a total-function-count constrained environment (i.e. Android), it can be better to have just these two functions instead of a larger number of overloads that it would take to accomplish the same job.

可能不希望使用默认参数值的地方:

  • 如果希望另一种JVM语言能够使用默认值,则需要使用显式重载或使用

  • When you want another JVM language to be able to use the defaulted values you either need to use explicit overloads or use the @JvmOverloads annotation which:

对于每个具有默认值的参数,这将产生一个额外的重载,该重载将删除此参数以及参数列表中右侧的所有参数.

For every parameter with a default value, this will generate one additional overload, which has this parameter and all parameters to the right of it in the parameter list removed.

  • 您具有库的先前版本,并且为了与二进制API兼容,添加默认参数可能会破坏与现有已编译代码的兼容性,而添加重载则不会.

  • You have a previous version of your library and for binary API compatibility adding a default parameter might break compatibility for existing compiled code whereas adding an overload would not.

    您具有以前的现有功能:

    You have a previous existing function:

    fun foo() = ...
    

    ,您需要保留该函数签名,但您还想添加另一个具有相同签名但带有附加可选参数的签名:

    and you need to retain that function signature, but you also want to add another with the same signature but additional optional parameter:

    fun foo() = ...
    fun foo(x: Int = 5) = ...   // never can be called using default value
    

    您将无法使用第二版的默认值(通过反射callBy除外).相反,所有不带参数的foo()调用仍会调用该函数的第一个版本.因此,您需要改用不带默认值的独特重载,否则将使函数的用户感到困惑:

    You will not be able to use the default value in the 2nd version (other than via reflection callBy). Instead all foo() calls without parameters still call the first version of the function. So you need to instead use distinct overloads without the default or you will confuse users of the function:

    fun foo() = ...  
    fun foo(x: Int) = ...
    

  • 您可能没有一起使用的参数,因此重载使您可以将参数分组为有意义的协调集.

  • You have arguments that may not make sense together, and therefore overloads allow you to group parameters into meaningful coordinated sets.

    具有默认值的调用方法必须执行另一步骤,以检查缺少哪些值并应用默认值,然后将调用转发给real方法.因此,在性能受限制的环境中(例如,方法调用上的Android,嵌入式,实时,十亿次循环迭代),可能不需要执行此额外检查.尽管如果您在性能分析中没有看到问题,那么这可能是一个虚构的问题,可能是JVM内联的,并且可能根本没有任何影响.先测量,再担心.

    Calling methods with default values has to do another step to check which values are missing and apply the defaults and then forward the call to the real method. So in a performance constrained environment (i.e. Android, embedded, real-time, billion loop iterations on a method call) this extra check may not be desired. Although if you do not see an issue in profiling, this might be an imaginary issue, might be inlined by the JVM, and may not have any impact at all. Measure first before worrying.

    不真正支持这两种情况的情况:

    如果您正在从其他语言中阅读有关此问题的一般论点...

    In case you are reading general arguments about this from other languages...

    • 针对类似问题的C#答案中,尊敬的乔恩·斯凯特(Jon Skeet)提到您应谨慎使用默认值如果它们可以在构建之间进行更改,那将是一个问题.在C#中,默认值位于调用站点,而在Kotlin中,对于非内联函数,它位于被调用的(桥)函数内部.因此,对于Kotlin来说,更改值的隐藏和显式默认值具有相同的影响,并且此参数不应影响决策.

    • in a C# answer for this similar question the esteemed Jon Skeet mentions that you should be careful using defaults if they could change between builds and that would be a problem. In C# the defaulting is at the call site, whereas in Kotlin for non-inlined functions it is inside of the (bridge) function being called. Therefore for Kotlin it is the same impact for changing hidden and explicit defaulting of values and this argument should not impact the decision.

    也在C#中回答说,如果团队成员对使用默认参数有相反的看法,那么也许不要使用它们.这不应应用于Kotlin,因为它们是核心语言功能,并且自1.0之前的版本开始在标准库中使用,并且不支持限制其使用.相对的团队成员应默认使用默认参数,除非他们有确定的情况使它们无法使用.而在C#中,它是在该语言的生命周期中引入的较晚的,因此具有更多的可选采用"的感觉

    also in the C# answer saying that if team members have opposing views about use of defaulted arguments then maybe don't use them. This should not be applied to Kotlin as they are a core language feature and used in the standard library since before 1.0 and there is no support for restricting their use. The opposing team members should default to using defaulted arguments unless they have a definitive case that makes them unusable. Whereas in C# it was introduced much later in the life cycle of that language and therefore had a sense of more "optional adoption"

    这篇关于默认参数vs重载,何时使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆