Prepare to be amazed by the wonders of Kotlin! In this blog post, we’ll delve into 5 astonishing snippets that Will Make You Say Whoa, Kotlin!
1. Extension Functions:
Kotlin's extension functions enable you to introduce new functions to preexisting classes without altering their original code. This proves to be incredibly advantageous, especially when dealing with unmodifiable classes or aiming to maintain a tidy and well-structured codebase.Example 1:
fun View.gone(){
visibility =View.GONE
}
fun View.visible(){
visibility =View.VISIBLE
}
// Usage
textView.hide()
Example 2:
// Extension function to capitalize the first letter of a String
fun String.capitalizeFirstLetter(): String {
if (isEmpty()) return this
return substring(0, 1).toUpperCase() + substring(1)
}
// Usage
fun main() {
val input = "this is kotlin"
val outputString = input.capitalizeFirstLetter()
println(outputString)
}
// Output: This is kotlin
2. Improved by let, run, apply, and also: Kotlin Scope Function
To assist you in selecting the appropriate scope function for your needs, kindly refer to this table.
=>let function
- The context object : it
- The return value : lambda result
The `let` function is frequently employed to ensure calls are protected from null values. Utilize the safe call operator (?.) in combination with `let` for null safety. This ensures that the block runs only when the value is not null.
Example:
fun main() {
val str: String? = "Kotlin"
str?.let {
println("let() called on $it")
}
}
=>apply function
- The context object : this
- The return value : Context object
Example:
fun main() {
val user = User()
user.apply {
name="Foo"
}
println(user.name)
}
class User() {
lateinit var name: String
}
=>with function
- The context object: this
- The return value : lambda result.
Example:
fun main() {
val user = User()
user.apply {
name="Foo"
}
// with function
with(user) {
println(" $name ")
}
}
class User() {
lateinit var name: String
}
=>run function
- The context object : this
- The return value : lambda result
The "run" function can be described as a merger of the "let" and "with" functions.
Example:
fun main() {
var user: User? = null
// body only executes if User is non-null
user?.run {
print(name)
}
// re-initialize user
user = User().apply {
name = "Kotlin"
}
// body executes as 'User' is non-null
user?.run {
print("Name : $name")
}
}
class User() {
lateinit var name: String
}
// output:Name : Kotlin
=>also function
- The context object : it
- The return value : Context object
It's utilized in situations where we need to carry out extra tasks after the object members have been initialized.
Example:
fun main() {
// initialized
val list = mutableListOf<Int>(1, 2, 3)
// later if we want to perform
// multiple operations on this list
list.also {
it.add(4)
it.remove(2)
// more operations if needed
}
println(list)
}
// Output:[1, 3, 4]
3. Higher-Order Functions
In Kotlin, a Higher-Order function is a function that can take another function as an argument or return a function.
Example:
fun add(a: Int, b: Int): Int{
var sum = a + b
return sum
}
// higher-order function definition
fun higherfunc(addfunc:(Int,Int)-> Int){
// invoke regular function using local name
var result = addfunc(3,6)
print("The sum of two numbers is: $result")
}
fun main(args: Array<String>) {
// invoke higher-order function
higherfunc(::add)
}
// output::The sum of two numbers is: 9
4. Using when Expression
- In Kotlin, the when expression functions similarly to the switch statement in other programming languages, but it offers greater intelligence and flexibility.
- One neat aspect of using "when" in Kotlin is that you don't have to include a break statement like you do in languages such as Java. Once a match is found, it executes the corresponding code and then exits the when block.
- Replaces lengthy ‘if-else-if’ chains for cleaner conditional logic.
Example 1:With Range
val age = 20
when (age) {
in 18..25 -> println("Young adult")
in 26..60 -> println("Adult")
else -> println("Not considered an adult")
}
Example 2:Using when as an expression
fun main() {
var weekDay = 3
var day= when(weekDay) {
1->"Monday"
2->"Tuesday"
3->"Wednesday"
4->"Thursday"
5->"Friday"
6->"Saturday"
7->"Sunday"
else-> "Not a week day"
}
print(day)
}
Benefits:
- Enhanced code readability and maintainability.
- Avoids nested if statements for clearer logic.
5. Null Safety and Safe Cast Operator
- Null safety
Kotlin’s null safety feature, which is enforced by the compiler, is designed to prevent NullPointerExceptions by removing dangerous null references in the code.
var a: String = "kotlin" // Regular initialization means non-nullable by default
a = null // compilation error
To enable null values, you can define a variable as a nullable string by using String?:.
var b: String? = "kotlin" // can be set to null
b = null
print(b)
- Safe calls
The Kotlin safe call operator ?. lets you interact with a field or invoke a method on a variable that may be null. Specifically, this operator performs the action only if the variable isn't null; otherwise, it gives back null. For example:
fun main() {
val a: String? = "kotlin"
// it returns a's length, or null if a in null
println(a?.length)
// it returns a's value in uppercase, or null if a in null
println(a?.uppercase())
}
- Safe casts
Using regular casts can lead to a ClassCastException if the object isn't of the desired type. An alternative is to employ safe casts, which return null if the casting attempt fails.
val obj: Any = "Kotlin"
val str: String? = obj as? String