Skip to content

Commit 5f95082

Browse files
chore: update introduction
1 parent e3d46b5 commit 5f95082

File tree

7 files changed

+425
-25
lines changed

7 files changed

+425
-25
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Functions
2+
3+
### Default parameter values and named arguments
4+
5+
<div class="language-kotlin" theme="idea">
6+
7+
```kotlin
8+
fun printMessage(message: String): Unit { // 1
9+
println(message)
10+
}
11+
12+
fun printMessageWithPrefix(message: String, prefix : String = "") { // 2
13+
println("[$prefix] $message")
14+
}
15+
16+
fun sum(x: Int, y: Int): Int { // 3
17+
return x + y
18+
}
19+
20+
fun multiply(x: Int, y: Int) = x * y // 4
21+
22+
fun main() {
23+
printMessage("Hello") // 5
24+
printMessageWithPrefix("Hello", "Log") // 6
25+
printMessageWithPrefix("Hello") // 7
26+
printMessageWithPrefix(prefix = "Log", message = "Hello") // 8
27+
sum(1, 2)
28+
}
29+
```
30+
31+
</div>
32+
33+
1. Create a function that takes a parameter of type string and returns Unit (i.e. no return value).
34+
2. Create a function that takes a second optional parameter with default value empty String. Also return Unit, which can be omitted.
35+
3. Create a function that returns an integer.
36+
4. Create a single-expression function that returns an integer (inferred).
37+
5. Call a function passing as argument `Hello`.
38+
6. Call a function with two parameters, passing a value for the second optional parameter.
39+
7. Call a function with two parameters, ignoring the second one.
40+
8. Call a function using named parameters and changing order of arguments.
41+
42+
### Infix functions
43+
44+
Member functions and extensions with a single parameter can be turned into infix functions.
45+
46+
<div class="language-kotlin" theme="idea">
47+
48+
```kotlin
49+
fun main() {
50+
51+
infix fun Int.times(str: String) = str.repeat(this) // 1
52+
println(2 times "Bye ") // 2
53+
54+
val pair = "Ferrari" to "Katrina" // 3
55+
println(pair)
56+
57+
infix fun String.onto(other: String) = Pair(this, other) // 4
58+
val myPair = "McLaren" onto "Lucas"
59+
println(myPair)
60+
61+
val sophia = Person("Sophia")
62+
val claudia = Person("Claudia")
63+
sophia likes claudia // 5
64+
}
65+
66+
class Person(val name: String) {
67+
val likedPeople = mutableListOf<Person>()
68+
infix fun likes(other: Person) { likedPeople.add(other) } // 6
69+
}
70+
```
71+
72+
</div>
73+
74+
1. Defines an infix extension function on `Int`
75+
2. Call infix function `1`
76+
3. The infix function `to` from the standard library lets you easily create `Pair`s
77+
4. Here's your own implementation of `to` creatively called `onto`
78+
5. Extensions also work on members functions (methods).
79+
6. The containing class becomes the first parameter.
80+
81+
Note that the example uses _local functions_ (functions nested into another function).
82+
83+
### Operator functions
84+
85+
Certain functions can be "upgraded" to operators, allowing to use them with the corresponding operator symbol.
86+
87+
<div class="language-kotlin" theme="idea">
88+
89+
```kotlin
90+
fun main() {
91+
//sampleStart
92+
93+
operator fun Int.times(str: String) = str.repeat(this) // 1
94+
println(2 * "Bye ") // 2
95+
96+
operator fun String.get(range: IntRange) = substring(range) // 3
97+
val str = "Always forgive your enemies; nothing annoys them so much."
98+
println(str[0..14]) // 4
99+
//sampleEnd
100+
}
101+
```
102+
103+
</div>
104+
105+
1. This takes the infix function from above one step further using the `operator` modifier.
106+
2. The operator symbol for `times()` is `*` so that you can call the function using `2 * "Bye"`
107+
3. An operator function allowing easy range access on strings
108+
4. The `get()` operator enables bracket-access syntax
109+
110+
### Functions with `vararg` parameters
111+
112+
Varargs allow passing any number of arguments by comma-separating them.
113+
114+
<div class="language-kotlin" theme="idea">
115+
116+
```kotlin
117+
fun main() {
118+
//sampleStart
119+
fun printAll(vararg messages: String) { // 1
120+
for (m in messages) println(m)
121+
}
122+
printAll("Hello", "Hallo", "Salut", "Hola", "你好") // 2
123+
124+
fun printAllWithPrefix(vararg messages: String, prefix: String) { // 3
125+
for (m in messages) println(prefix + m)
126+
}
127+
printAllWithPrefix("Hello", "Hallo", "Salut", "Hola", "你好",
128+
prefix = "Greeting: ") // 4
129+
130+
fun log(vararg entries: String) {
131+
printAll(*entries) // 5
132+
}
133+
//sampleEnd
134+
}
135+
```
136+
137+
</div>
138+
139+
1. The `vararg` modifier turns a parameter into a vararg.
140+
2. This allows calling `printAll` with any number of string arguments.
141+
3. Thanks to named parameters, you can even add another parameter of the same type after the vararg. This wouldn't be allowed in Java because there's no way to pass a value.
142+
4. Using named parameters, you can set a value to `prefix` despite the vararg.
143+
5. At runtime, a vararg is simply an array. To pass it along into a vararg parameter, you can use the special spread operator `*foo` to pass in `*entries` (a vararg of `String`) instead of `entries` (an `Array<String>`).

examples/01_introduction/03_Equality Checks.md

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Variables
2+
3+
Kotlin has powerful type inference. While you can explicitly declare the type of a variable, you'll usually let the
4+
compiler do the work by inferring it. While Kotlin does not enforce immutability, it is recommended.
5+
In essence use *val* over *var*.
6+
7+
<div class="language-kotlin" theme="idea">
8+
9+
```kotlin
10+
fun main() {
11+
//sampleStart
12+
var a: String = "initial" // 1
13+
println(a)
14+
val b: Int = 1 // 2
15+
val c = 3 // 3
16+
//sampleEnd
17+
}
18+
```
19+
20+
</div>
21+
22+
1. Declare a mutable variable and initialise it
23+
2. Declare an immutable variable and initialise it
24+
3. Declare an immutable variable and initialise it. The compiler infers the type.
25+
26+
<div class="language-kotlin" theme="idea">
27+
28+
```kotlin
29+
fun main() {
30+
//sampleStart
31+
var e: Int // 1
32+
println(e) // 2
33+
//sampleEnd
34+
}
35+
```
36+
37+
</div>
38+
39+
1. Declare a variable, but don't initialise it.
40+
2. Produces compiler error: Variable 'e' must be initialized
41+
42+
Variable initialization can be postponed, but it must be initialized before the first read.
43+
44+
<div class="language-kotlin" theme="idea">
45+
46+
```kotlin
47+
fun someCondition() = true
48+
49+
fun main() {
50+
//sampleStart
51+
val d: Int // 1
52+
53+
if (someCondition()) {
54+
d = 1 // 2
55+
} else {
56+
d = 2 // 2
57+
}
58+
59+
println(d) // 3
60+
//sampleEnd
61+
}
62+
```
63+
64+
</div>
65+
66+
1. Declare a variable, but don't initialise it.
67+
2. Initialize variable with different values depending on some condition.
68+
3. The first use of the variable.
File renamed without changes.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Classes
2+
3+
The class declaration consists of the class name, the class header (specifying its type parameters,
4+
the primary constructor etc.) and the class body, surrounded by curly braces.
5+
Both the header and the body are optional; if the class has no body, curly braces can be omitted.
6+
7+
<div class="language-kotlin" theme="idea">
8+
9+
```kotlin
10+
class Customer // 1
11+
12+
class Contact(val id: Int, var email: String) // 2
13+
14+
fun main() {
15+
16+
val customer = Customer() // 3
17+
18+
val contact = Contact(1, "[email protected]") // 4
19+
20+
println(contact.id) // 5
21+
contact.email = "[email protected]" // 6
22+
}
23+
```
24+
25+
</div>
26+
27+
28+
1. Declare a class named `Customer` with parameterless constructor
29+
2. Declare a class with an immutable property `id`, a mutable property `email` and constructor with two parameters `id` and `name`
30+
3. Create an instance of the class `Customer`
31+
4. Create an instance of the class `Contact` using the constructor with two arguments
32+
5. Access the property `id`
33+
6. Write to the property `email`
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Generics
2+
3+
Generics are one genericity mechanism that's become standard in modern languages. Generic classes and functions increase code reusability by encapsulating common logic that is independent of a particular generic type, like the logic inside a `List<T>` is independent of what `T` is.
4+
5+
### Generic classes
6+
7+
The first way to use generics in Kotlin is creating generic classes.
8+
9+
<div class="language-kotlin" theme="idea">
10+
11+
```kotlin
12+
//sampleStart
13+
class MutableStack<E>(vararg items: E) { // 1
14+
15+
private val elements = items.toMutableList()
16+
17+
fun push(element: E) = elements.add(element) // 2
18+
19+
fun peek(): E = elements.last() // 3
20+
21+
fun pop(): E = elements.removeAt(elements.size - 1)
22+
23+
fun isEmpty() = elements.isEmpty()
24+
25+
fun size() = elements.size
26+
27+
override fun toString() = "MutableStack(${elements.joinToString()})"
28+
}
29+
//sampleEnd
30+
31+
fun main() {
32+
val stack = MutableStack(0.62, 3.14, 2.7)
33+
stack.push(9.87)
34+
println(stack)
35+
36+
println("peek(): ${stack.peek()}")
37+
println(stack)
38+
39+
for (i in 1..stack.size()) {
40+
println("pop(): ${stack.pop()}")
41+
println(stack)
42+
}
43+
}
44+
45+
```
46+
47+
</div>
48+
49+
1. Defines a generic class `MutableStack<E>` where `E` is called the _generic type parameter_. At use-site, it is assigned to a concrete type such as `Int` by declaring a `MutableStack<Int>`.
50+
2. Inside the generic class, `E` can be used as a parameter like any other type.
51+
3. You can also use `E` as a return type.
52+
53+
Note that the implementation makes heavy use of Kotlin's shorthand syntax for functions that can be defined in a single expression.
54+
55+
56+
### Generic functions
57+
58+
You can also generify functions if their logic is independent of the concrete type. For instance, you can create a utility function to create mutable stacks more easily:
59+
60+
<div class="language-kotlin" theme="idea">
61+
62+
```kotlin
63+
class MutableStack<E>(vararg items: E) { // 1
64+
65+
private val elements = items.toMutableList()
66+
67+
fun push(element: E) = elements.add(element) // 2
68+
69+
fun peek(): E = elements.last() // 3
70+
71+
fun pop(): E = elements.removeAt(elements.size - 1)
72+
73+
fun isEmpty() = elements.isEmpty()
74+
75+
fun size() = elements.size
76+
77+
override fun toString() = "MutableStack(${elements.joinToString()})"
78+
}
79+
80+
//sampleStart
81+
fun <E> mutableStackOf(vararg elements: E) = MutableStack(*elements)
82+
83+
fun main() {
84+
val stack = mutableStackOf(0.62, 3.14, 2.7)
85+
}
86+
//sampleEnd
87+
```
88+
89+
</div>
90+
91+
Note how to compiler can infer the generic type from the parameters of `mutableStackOf` so that you don't have to write `mutableStackOf<Int>(...)`.

0 commit comments

Comments
 (0)