May
25th,
2021
- Use
vararg
for variable arguments:fun printLetters(vararg letters: String, count: Int): Unit { print("$count letters are ") for (letter in letters) print(letter) println() }
Then we can use it by calling:
printLetters("a", "c", "q", count = 3)
Or use
*
to pass an array as parameters:val argArray = arrayOf("q","e","w") printLetters(*argArray, count = 3)
- An example of
fold
function:fun cal(list: List<Int>): Int { return list.fold(0){ res, el -> res * el + el } }
If we call:
println( cal( listOf(1, 2, 3) ) )
It will print
15
as the process below:
0 * 1 + 1 = 1
1 * 2 + 2 = 4
4 * 3 + 3 = 15
- infix function
to
returns paired data structure which is usually combined withmap
:mapOf( 1 to "one", 2 to "two", 3 to "three" )
- A simple infix function example:
class Person { infix fun called(name: String) { println("My name is $name.") } }
To call it:
val p = Person() //infix style p called "Shaw" //or use it as a regular function p.called("Shaw")
- Kotlin can declare abstract properties in
interface
. However, it cannot be assigned a value onto them:interface Flyer { //WRONG val height: Int = 1000 //CORRECT val height: Int get() = 1000 }
- Usage of
coerceIn
:println(0.coerceIn(1, 100)) // 1 println(500.coerceIn(1, 100)) // 100
- Use
require
to add rules for parameters of a class ininit
block:class Robot ( val code: String, val battery: String? = null, val weight: Int? = null ) { init { require (weight == null || battery != null) { "Weight cannot be set with no battery assigned." } } }
In this case, if we call
val robot = Robot(code="001", weight=100)
, anIllegalArgumentException
will be thrown because the rule we set cannot be satisfied. - Use
Delegates.observable()
to implement observer pattern, unlike Java’sObservable()
which only provide oneupdate()
method for overriding,Delegates.observable()
provide 3 parameters (property itself for delegating, oldValue, newValue) which shows powerful ability to customize:interface PriceUpdateListener { fun onRise(price: Int) fun onFall(price: Int) } class PriceDisplayer: PriceUpdateListener { override fun onRise(price: Int) { println("Price has risen to ${price}.") } override fun onFall(price: Int) { println("Price has fallen to ${price}.") } } class PriceUpdater { var listeners = mutableSetOf<PriceUpdateListener>() var price: Int by Delegates.observable(0) { _, old, new -> //0 is initial value, (_, old, new) are the 3 parameters mentioned above listeners.forEach { if (new > old) it.onRise(price) else it.onFall(price) } } } fun main (args: Array<String>) { val priceUpdater = PriceUpdater() val priceDispalyer = PriceDisplayer() priceUpdater.listeners.add(priceDispalyer) priceUpdater.price = 50 priceUpdater.price = 40 }
Delegates.vetoable()
can be used when you want to make sure the assignment follows your rule before a new value is assigned to the target:var value: Int by Delegates.vetoable(0) { prop, old, new -> new > 0 }
In this case:
>>> value = 1 >>> println(value) 1
>>> value = -1 //will be intercepted because -1 does not satisfy the rule (greater than 0) >>> println(value) 1