Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin default parameter ordering

Does anyone know why the call to method1 does not compile whereas the call to method2 does?

class MyApp {

    interface X {

        fun <Q : Any, A : Any> method1(argStr: String = "", argQ: Q, argH: (A) -> Unit)

        fun <Q : Any, A : Any> method2(argQ: Q, argStr: String = "", argH: (A) -> Unit)
    }

    fun test(x: X) {

        /* Call to method1 does not work - the following errors are produced
         * Error: Kotlin: Type inference failed:
         * fun <Q : Any, A : Any> method1(argStr: String = ..., argQ: Q, argH: (A) -> Unit): Unit
         * cannot be applied to (Int,(Int) -> Unit)
         * Error: Kotlin: The integer literal does not conform to the expected type String
         * Error: Kotlin: No value passed for parameter 'argQ'
         */
        
        x.method1(1) { res: Int -> println(res) }

        /* No errors here */
        x.method2(1) { res: Int -> println(res) }
    }

}
like image 245
auser Avatar asked Sep 08 '26 23:09

auser


2 Answers

If a default parameter precedes a parameter with no default value, the default value can only be used by calling the function with named arguments.

Example:

fun foo(bar: Int = 0, baz: Int) { ... }

foo(baz = 1) // The default value bar = 0 is used

In your example this will work:

x.method1(argQ = 1) { res: Int -> println(res) } // The default value argStr = "" is used

Further reading

like image 58
minhazur Avatar answered Sep 11 '26 13:09

minhazur


It is possible to place a parameter with a default value before a regular parameter (no default value). However, you have to keep in mind the following:

  1. The value for the regular parameter will be required, so the caller will be forced to always provide a value for the parameter with default argument which makes meaningless the purpose of having a default argument. The following will work:
x.method1("", 1) { res: Int -> println(res) }
  1. The caller may skip the default parameter if they use named arguments. This is the reason the following works:
x.method1(argQ = 1) { res: Int -> println(res) }

It is always a good idea to put parameters with default parameters in trailing positions unless the last parameter stands for a lambda expression.

like image 38
lmiguelvargasf Avatar answered Sep 11 '26 13:09

lmiguelvargasf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!