0, "'n' must be non-negative, but was $n.") // ... } fun require(value: Boolean, message: String) { if (!value) throw IllegalArgumentException(message) }
0) { "'n' must be non-negative, but was $n." } // ... } fun require(value: Boolean, lazyMessage: () -> String) { if (!value) throw IllegalArgumentException(lazyMessage()) }
0) { "'n' must be non-negative, but was $n." } // ... } inline fun require(value: Boolean, lazyMessage: () -> String) { if (!value) throw IllegalArgumentException(lazyMessage()) }
0)) throw IllegalArgumentException("'n' must be non-negative, but was $n.") // ... } inline fun require(value: Boolean, lazyMessage: () -> String) { if (!value) throw IllegalArgumentException(lazyMessage()) }
Byte inline fun String.toShort(radix: Int = 10): Short inline fun String.toInt(radix: Int = 10): Int inline fun String.toLong(radix: Int = 10): Long inline fun String.toFloat(): Float inline fun String.toDouble(): Double inline fun String.toBoolean(): Boolean inline fun Byte.toString(radix: Int): String inline fun Short.toString(radix: Int): String inline fun Int.toString(radix: Int): String inline fun Long.toString(radix: Int): String fun String.toByteOrNull(radix: Int = 10): Byte? fun String.toShortOrNull(radix: Int = 10): Short? fun String.toIntOrNull(radix: Int = 10): Int? fun String.toLongOrNull(radix: Int = 10): Long? fun String.toFloatOrNull(): Float? fun String.toDoubleOrNull(): Double?
b, a += b operator fun minus(other: P): R // a - b, a -= b operator fun times(other: P): R // a * b, a *= b operator fun div(other: P): R // a / b, a /= b operator fun rem(other: P): R // a % b, a %= b operator fun plusAssign(other: P): Unit // a += b operator fun minusAssign(other: P): Unit // a -= b operator fun timesAssign(other: P): Unit // a *= b operator fun divAssign(other: P): Unit // a /= b operator fun remAssign(other: P): Unit // a %= b operator fun unaryPlus(): R // +a operator fun unaryMinus(): R // -a operator fun inc(): MyType // a++, ++a operator fun dec(): MyType // a--, --a operator fun not(): R // !a operator fun compareTo(other: P): Int // a >= b, a > b, a < b, a <= b operator fun equals(other: Any?): Boolean // a == b, a != b operator fun contains(other: P): Boolean // b in a, b !in a
// a(p1, ..., pN) operator fun get(p1: P1, ..., pN: PN): R // a[p1, ..., pN] operator fun set(p1: P1, ..., pN: PN, t: T): Unit // a[p1, ..., pN] = t operator fun rangeTo(other: P): R // a..b operator fun component1(): R // val myVal = MyType() operator fun componentN(): R // val (c1, ..., cN) = myVal operator fun iterator(): PseudoIterator // val myVal = MyType() // for (i in myVal) { class PseudoIterator { // ... operator fun next(): R // } operator fun hasNext(): Boolean }
// a(p1, ..., pN) operator fun get(p1: P1, ..., pN: PN): R // a[p1, ..., pN] operator fun set(p1: P1, ..., pN: PN, t: T): Unit // a[p1, ..., pN] = t operator fun rangeTo(other: P): R // a..b operator fun component1(): R // val myVal = MyType() operator fun componentN(): R // val (c1, ..., cN) = myVal operator fun iterator(): PseudoIterator // val myVal = MyType() // for (i in myVal) { class PseudoIterator { // ... operator fun next(): R // } operator fun hasNext(): Boolean }
var divider: Int init { val pow10 = if (value == 0) 1 else Math.log10(value.toDouble()).toInt() divider = Math.pow(10.0, pow10.toDouble()).toInt() } operator fun next(): Int { val res = value / divider value %= divider divider /= 10 return res } operator fun hasNext() = divider > 0 }
{ nameView.text = user.name ageView.text = user.age } } Error! Smart cast to ‘User’ is impossible, because ‘user’ is a mutable property that could have been changed by this time. Function Literals with Receiver
block(this) var user: User? fun renderUser() { val usr = user if (usr != null) { nameView.text = usr.name ageView.text = usr.age } } Function Literals with Receiver
block(this) var user: User? fun renderUser() { user?.let { // ‘user’ is not null nameView.text = it.name ageView.text = it.age } } Function Literals with Receiver
block(this) var user: User? fun renderUser() { user?.let { // ‘user’ is not null and nameView.text = it.name ageView.text = it.age } } Function Literals with Receiver
block(this) var user: User? fun renderUser() { user?.let { // ‘user’ is not null and it was already read into local val nameView.text = it.name ageView.text = it.age } } Function Literals with Receiver
-> R): R = block(this) fun fetchData() { getResponse()?.let { // result of ‘getResponse()’ was already read/delivered/calculated logResponse(it) saveData(parseData(it)) } }
Unit): T { block(); return this } inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this } inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() inline fun <T, R> T.let(block: (T) -> R): R = block(this) inline fun <T, R> T.run(block: T.() -> R): R = block() inline fun <R> run(block: () -> R): R = block()
<T> List<T>.component5(): T operator fun <T> Iterable<T>.contains(element: T): Boolean operator fun <T> Collection<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.plus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> operator fun <T> Iterable<T>.minus(T|Array<out T>|Iterable<T>|Sequence<T>): List<T> if ("Jan" in months) { // ... }
T): Int inline fun <T> Iterable<T>.indexOfFirst(predicate: (T) -> Boolean): Int inline fun <T> Iterable<T>.indexOfLast(predicate: (T) -> Boolean): Int fun <T> List<T>.binarySearch([from: Int, to: Int,] comparison: (T) -> Int): Int fun <T: Comparable<T>> List<T?>.binarySearch(elem: T?, [from: Int, to: Int]): Int fun <T> List<T>. binarySearch(elem: T, comparator: Comparator<in T>, [from: Int, to: Int]): Int inline fun <T, K: Comparable<K>> List<T>. binarySearchBy(key: K?, [from: Int, to: Int,] selector: (T) -> K?): Int
Iterable<T>.sortedDescending(): List<T> fun <T: Comparable<T>> MutableList<T>.sort(): Unit fun <T: Comparable<T>> MutableList<T>.sortDescending(): Unit inline fun <T, R: Comparable<R>> Iterable<T>.sortedBy(selector: (T) -> R?): List<T> inline fun <T, R: Comparable<R>> Iterable<T>.sortedByDescending(selector: (T) -> R?): List<T> inline fun <T, R: Comparable<R>> MutableList<T>.sortBy(selector: (T) -> R?): Unit inline fun <T, R: Comparable<R>> MutableList<T>.sortByDescending(selector: (T) -> R?): Unit fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T> fun <T> MutableList<T>.sortWith(comparator: Comparator<in T>): Unit
MutableList<T>.reverse(): Unit fun <T> List<T>.asReversed(): List<T> fun <T> MutableList<T>.asReversed(): MutableList<T> fun <T> List<T>.slice(indices: IntRange): List<T> fun <T> List<T>.slice(indices: Iterable<Int>): List<T>
fun <T> Iterable<T>.toList(): List<T> fun <T> Iterable<T>.toMutableList(): MutableList<T> fun <T> Iterable<T>.toSet(): Set<T> fun <T> Iterable<T>.toMutableSet(): MutableSet<T> fun <T> Iterable<T>.toHashSet(): HashSet<T> fun <T: Comparable<T>> Iterable<T>.toSortedSet([comparator: Comparator<in T>]): SortedSet<T> inline fun <reified T> Collection<T>.toTypedArray(): Array<T> inline fun <T> Iterable<T>.asIterable(): Iterable<T> fun <T> Iterable<T>.asSequence(): Sequence<T>
fun <T> Iterable<T>.toList(): List<T> fun <T> Iterable<T>.toMutableList(): MutableList<T> fun <T> Iterable<T>.toSet(): Set<T> fun <T> Iterable<T>.toMutableSet(): MutableSet<T> fun <T> Iterable<T>.toHashSet(): HashSet<T> fun <T: Comparable<T>> Iterable<T>.toSortedSet([comparator: Comparator<in T>]): SortedSet<T> inline fun <reified T> Collection<T>.toTypedArray(): Array<T> inline fun <T> Iterable<T>.asIterable(): Iterable<T> fun <T> Iterable<T>.asSequence(): Sequence<T>
fun <T> Iterable<T>.toList(): List<T> fun <T> Iterable<T>.toMutableList(): MutableList<T> fun <T> Iterable<T>.toSet(): Set<T> fun <T> Iterable<T>.toMutableSet(): MutableSet<T> fun <T> Iterable<T>.toHashSet(): HashSet<T> fun <T: Comparable<T>> Iterable<T>.toSortedSet([comparator: Comparator<in T>]): SortedSet<T> inline fun <reified T> Collection<T>.toTypedArray(): Array<T> inline fun <T> Iterable<T>.asIterable(): Iterable<T> fun <T> Iterable<T>.asSequence(): Sequence<T>
mutableMapOf<String, Int>() for (item in list) { if (item !in map) { map[item] = 0 } map[item] = map[item] + 1 } return map } Error! Operator plus is not allowed on a nullable receiver.
-> R): R inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R fun InputStream.readLines(): List<String> = BufferedReader(InputStreamReader(this)).use { val lines = arrayListOf<String>() var line = it.readLine() while (line != null) { lines += line line = it.readLine() } lines }
fun Reader.readText(): String fun Reader.readLines(): List<String> fun BufferedReader.lineSequence(): Sequence<String> inline fun <T> Reader.useLines(block: (Sequence<String>) -> T): T fun Reader.forEachLine(action: (String) -> Unit): Unit fun Reader.copyTo(out: Writer, [bufferSize: Int]): Long IO. Text Streams
File.appendBytes(array: ByteArray): Unit fun File.readText([charset: Charset]): String fun File.writeText(text: String, [charset: Charset]): Unit fun File.appendText(text: String, [charset: Charset]): Unit fun File.readLines([charset: Charset]): List<String> inline fun <T> File.useLines([charset: Charset], block: (Sequence<String>) -> T): T fun File.forEachLine([charset: Charset], action: (String) -> Unit): Unit fun File.forEachBlock([blockSize: Int,] action: (buffer: ByteArray, bytesRead: Int) -> Unit): Unit
String fun File.toRelativeString(base: File): String fun File.relativeTo(base: File): File fun File.relativeToOrSelf(base: File): File fun File.relativeToOrNull(base: File): File? fun File.resolve(relative: String|File): File fun File.resolveSibling(relative: String|File): File fun File.startsWith(other: String|File): Boolean fun File.endsWith(other: String|File): Boolean
inline fun <T> ReentrantReadWriteLock.read(action: () -> T): T inline fun <T> ReentrantReadWriteLock.write(action: () -> T): T val dbLock = ReentrantReadWriteLock() dbLock.write { writeToDb(entity) }
measureTimeMillis(block: () -> Unit) : Long val saveTime = measureNanoTime { writeToDb(entity) } println("Saving is soo sloow ${saveTime}ns") Goodies. System
in public inline functions • Reified functions are not present in bytecode • Eager collection processing functions • Use Sequence • “as”/”to” prefix convention • Ranges optimisations
inline fun <reified T : View> Activity.findOptional(@IdRes id: Int): T? val callBtn = findViewById(R.id.callBtn) as Button val callBtn = find<Button>(R.id.callBtn) Anko. What else? ViewUtils