You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/topics/functions.md
+91-55Lines changed: 91 additions & 55 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,12 +44,13 @@ fun powerOf(
44
44
This helps with refactorings and code maintenance:
45
45
you can move parameters within the declaration without worrying about which is going to be the last one.
46
46
47
-
TODO should this be optional parameters? probably not
48
-
### Parameters with default values
47
+
### Parameters with default values (optional parameters)
49
48
50
49
Function parameters can have default values, which are used when you skip the corresponding argument.
51
-
A default value is set by appending `=` to the type.
52
-
This reduces the number of overloads:
50
+
This reduces the number of necessary overloads.
51
+
Parameters with default values are also referred to as _optional parameters_.
52
+
53
+
A default value is set by appending `=` to the parameter declaration:
53
54
54
55
```kotlin
55
56
funread(
@@ -59,50 +60,85 @@ fun read(
59
60
) { /*...*/ }
60
61
```
61
62
62
-
Such parameters are also referred to as _optional parameters_.
63
+
If a parameter with default value precedes a parameter with no default value, the default value can only be used by calling
64
+
the function with [named arguments](#named-arguments):
65
+
66
+
```kotlin
67
+
funfoo(
68
+
foo:Int = 0,
69
+
bar:Int,
70
+
) { /*...*/ }
63
71
64
-
Overriding methods always use the base method's default parameter values.
72
+
foo(bar =1) // Uses the default value foo = 0
73
+
foo(1) // Error: No value passed for parameter 'bar'
74
+
```
75
+
76
+
[Overriding methods](inheritance.md#overriding-methods) always use the base method's default parameter values.
65
77
When overriding a method that has default parameter values, the default parameter values must be omitted from the signature:
66
78
67
79
```kotlin
68
80
openclassA {
69
-
openfunfoo(i:Int = 10) { /*...*/ }
81
+
openfunfoo(i:Int = 10, j:Int = 0) { /*...*/ }
70
82
}
71
83
72
84
classB : A() {
73
-
overridefunfoo(i:Int) { /*...*/ } // No default value is allowed.
85
+
// It's not allowed to specify default values here
86
+
// but this function also uses 10 for 'i' and 0 for 'j'
87
+
// by default.
88
+
overridefunfoo(i:Int, j:Int) { /*...*/ }
74
89
}
75
90
```
76
91
77
-
If a parameter with default value precedes a parameter with no default value, the default value can only be used by calling
78
-
the function with [named arguments](#named-arguments):
92
+
#### Non-constant expressions as default values
93
+
94
+
You can assign to a parameter a default value that is not constant an expression, as in a function call, or a calculation that uses
95
+
values of other arguments, like the `len` parameter in the example above:
79
96
80
97
```kotlin
81
-
funfoo(
82
-
bar:Int = 0,
83
-
baz:Int,
98
+
funread(
99
+
b:ByteArray,
100
+
off:Int = 0,
101
+
len:Int = b.size,
102
+
) { /*...*/ }
103
+
```
104
+
105
+
Parameters referring to other parameters' values must be declared later in the order (in this example, `len` must be declared after `b`).
106
+
107
+
In general default value of a parameter can be any expression — but such expressions are only calculated when
108
+
the function is called **without** the parameter and a default value needs to be assigned.
109
+
For example, this function prints out a line when it is called without the `print` parameter:
110
+
111
+
```kotlin
112
+
funread(
113
+
b:Int,
114
+
print:Unit? = println("No argument passed for 'print'.")
84
115
) { /*...*/ }
85
116
86
-
foo(baz =1) // The default value bar = 0 is used
117
+
funmain() {
118
+
read (1)
119
+
}
87
120
```
88
121
89
-
TODO this doesn't seem to do much with the subject of default values.
90
-
If the last parameter after all parameters with default values has a functional type,
122
+
If the last parameter in a function declaration has a functional type,
91
123
then you can pass the corresponding [lambda](lambdas.md#lambda-expression-syntax) argument either as a named argument or [outside the parentheses](lambdas.md#passing-trailing-lambdas):
92
124
93
125
```kotlin
94
126
funfoo(
95
-
bar:Int = 0,
96
-
baz:Int = 1,
127
+
foo:Int = 0,
128
+
bar:Int = 1,
97
129
qux: () ->Unit,
98
130
) { /*...*/ }
99
131
100
-
foo(1) { println("hello") } // Uses the default value baz = 1
101
-
foo(qux = { println("hello") }) // Uses both default values bar = 0 and baz = 1
102
-
foo { println("hello") } // Uses both default values bar = 0 and baz = 1
132
+
// Uses the default value bar = 1
133
+
foo(1) { println("hello") }
134
+
135
+
// Uses both default values foo = 0 and bar = 1
136
+
foo(qux = { println("hello") })
137
+
138
+
// Uses both default values foo = 0 and bar = 1
139
+
foo { println("hello") }
103
140
```
104
141
105
-
TODO should named arguments be before default values? Should arguments be parameters?
106
142
### Named arguments
107
143
108
144
You can name one or more of a function's arguments when calling it. This can be helpful when a function has many
@@ -148,55 +184,43 @@ skipped argument, you must name all subsequent arguments:
148
184
reformat("This is a short String!", upperCaseFirstLetter =false, wordSeparator ='_')
149
185
```
150
186
151
-
You can pass a [variable number of arguments (`vararg`)](#variable-number-of-arguments-varargs) with names using the
152
-
_spread_ operator (prefix the array with `*`):
187
+
You can pass a [variable number of arguments](#variable-number-of-arguments-varargs) (`vararg`) naming the correspoding array:
153
188
154
189
```kotlin
155
190
funfoo(varargstrings:String) { /*...*/ }
156
191
157
-
foo(strings =*arrayOf("a", "b", "c"))
192
+
foo(strings = arrayOf("a", "b", "c"))
158
193
```
159
194
195
+
<!-- Rationale for named arguments interaction with varargs is here https://youtrack.jetbrains.com/issue/KT-52505#focus=Comments-27-6147916.0-0 -->
196
+
160
197
> When calling Java functions on the JVM, you can't use the named argument syntax because Java bytecode does not
161
198
> always preserve the names of function parameters.
162
199
>
163
200
{style="note"}
164
201
165
202
### Unit-returning functions
166
203
167
-
If a function does not return a useful value, its return type is `Unit`. `Unit` is a type with only one value - `Unit`.
168
-
This value does not have to be returned explicitly:
204
+
If a function does not return a useful value, its return type is `Unit` (corresponds to the `void` type in Java).
205
+
206
+
`Unit` is a type with only one value - `Unit`.
207
+
You don't have to declare this return type, or return `Unit` explicitly.
208
+
Therefore, this verbose declaration:
169
209
170
210
```kotlin
171
211
funprintHello(name:String?): Unit {
172
212
if (name !=null)
173
213
println("Hello $name")
174
214
else
175
215
println("Hi there!")
176
-
// `return Unit` or `return` is optional
216
+
returnUnit
177
217
}
178
218
```
179
219
180
-
TODO this can be folded into above surely
181
-
The `Unit` return type declaration is also optional. The above code is equivalent to:
220
+
is equivalent to:
182
221
183
222
```kotlin
184
-
funprintHello(name:String?) { ... }
185
-
```
186
-
187
-
TODO since this refers to explicit return types, should probably be below them.
188
-
### Single-expression functions
189
-
190
-
When the function body consists of a single expression, the curly braces can be omitted and the body specified after an `=` symbol:
191
-
192
-
```kotlin
193
-
fundouble(x:Int): Int= x *2
194
-
```
195
-
196
-
Explicitly declaring the return type is [optional](#explicit-return-types) when this can be inferred by the compiler:
197
-
198
-
```kotlin
199
-
fundouble(x:Int) = x *2
223
+
funprintHello(name:String?) { /*...*/ }
200
224
```
201
225
202
226
### Explicit return types
@@ -249,6 +273,20 @@ val a = intArrayOf(1, 2, 3) // IntArray is a primitive type array
249
273
val list = asList(-1, 0, *a.toTypedArray(), 4)
250
274
```
251
275
276
+
### Single-expression functions
277
+
278
+
When the function body consists of a single expression, the curly braces can be omitted and the body specified after an `=` symbol:
279
+
280
+
```kotlin
281
+
fundouble(x:Int): Int= x *2
282
+
```
283
+
284
+
Explicitly declaring the return type is [optional](#explicit-return-types) when this can be inferred by the compiler:
285
+
286
+
```kotlin
287
+
fundouble(x:Int) = x *2
288
+
```
289
+
252
290
### Infix notation
253
291
254
292
Functions marked with the `infix` keyword can also be called using the infix notation (omitting the dot and the parentheses
@@ -300,10 +338,8 @@ class MyStringCollection {
300
338
301
339
## Function scope
302
340
303
-
TODO is comparison to other languages even necessary here
304
-
Kotlin functions can be declared at the top level in a file, meaning you do not need to create a class to hold a function,
305
-
which you are required to do in languages such as Java and C#. In addition
306
-
to top level functions, Kotlin functions can also be declared locally as member functions and extension functions.
341
+
Kotlin functions can be declared at the top level in a file, meaning you do not need to create a class to hold a function.
342
+
Functions can also be declared locally as _member functions_ and _extension functions_.
307
343
308
344
### Local functions
309
345
@@ -375,10 +411,10 @@ the recursion, leaving behind a fast and efficient loop based version instead:
375
411
val eps = 1E-10// "good enough", could be 10^-15
376
412
377
413
tailrecfunfindFixPoint(x:Double = 1.0): Double=
378
-
if (Math.abs(x -Math.cos(x)) < eps) x else findFixPoint(Math.cos(x))
414
+
if (abs(x - cos(x)) < eps) x else findFixPoint(cos(x))
379
415
```
380
416
381
-
This code calculates the fixed point of cosine (a mathematical constant). It simply calls `Math.cos` repeatedly
417
+
This code calculates the fixed point of cosine (a mathematical constant). It simply calls `cos()` repeatedly
382
418
starting at `1.0` until the result no longer changes, yielding a result of `0.7390851332151611` for the specified
383
419
`eps` precision. The resulting code is equivalent to this more traditional style:
384
420
@@ -388,9 +424,9 @@ val eps = 1E-10 // "good enough", could be 10^-15
0 commit comments