May
25th,
2021
- Use
varargfor 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
foldfunction: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
15as the process below:
0 * 1 + 1 = 1
1 * 2 + 2 = 4
4 * 3 + 3 = 15 - infix function
toreturns 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
requireto add rules for parameters of a class ininitblock: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), anIllegalArgumentExceptionwill 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