ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
Sprint Part 3
otlin Advanced
Kirill Rozov
Senior Android Developer krl.rozov@gmail.com
Delegated Properties
Lazy Properties
class Address {
val id: Long = ¡­
var name: String = ¡­
var street: String = ¡­
val fullInfo by lazy { "$id $name $street" }
}
Delegated properties
class Example {
var p: String by Delegates()
}
Delegated properties
private class NotNullVar<T: Any>() : ReadWriteProperty<Any?, T> {
private var value: T? = null
public override fun getValue(thisRef: Any?, prop: KProperty<*>): T {
return value ?: throw IllegalStateException(¡­)
}
public override fun setValue(thisRef: Any?, prop: KProperty<*>, value: T) {
this.value = value
}
}
Delegated properties
operator fun getValue(thisRef: Any?, prop: KProperty<*>): T {
return value ?: throw IllegalStateException(¡­)
}
operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: T) {
this.value = value
}
Delegated properties
operator fun getValue(thisRef: Any?, prop: KProperty<*>): T {
return value ?: throw IllegalStateException(¡­)
}
operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: T) {
this.value = value
}
Objects
Object declaration
object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ...
}
val allDataProviders: Collection<DataProvider>
get() = // ...
}
Object declaration
object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ...
}
val allDataProviders: Collection<DataProvider>
get() = // ...
}
Object declaration
DataProviderManager.registerDataProvider(...)
Object expression
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
Object expression
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
Functional Programming
High-Order Functions
fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
}
finally {
lock.unlock()
}
}
High-Order Functions
fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
}
finally {
lock.unlock()
}
}
High-Order Functions
(Type1, Type2, ¡­, TypeN) -> TypeOut
High-Order Functions
fun toBeSynchronized() {
sharedResource.operation()
}
val result = lock(lock, ::toBeSynchronized)
High-Order Functions
fun toBeSynchronized() {
sharedResource.operation()
}
val result = lock(lock, ::toBeSynchronized)
Lambdas
lock(lock, { sharedResource.operation() })
Lambdas
lock(lock, { sharedResource.operation() })
Lambdas
{ name1: Type1, ¡­, nameN: TypeN -> ¡­ }
Lambdas
val sum = { x: Int, y: Int -> x + y }
Lambdas
val sum: (Int, Int) -> Int = { x, y -> x + y }
Lambdas
val sum: (Int, Int) -> Int = { x, y -> x + y }
Lambdas
lock (lock) {
sharedResource.operation()
}
Lambdas
fun <T, R> List<T>.map(transform: (T) -> R): List<R>
Lambdas
fun <T, R> List<T>.map(transform: (T) -> R): List<R>
Lambdas
fun <T, R> List<T>.map(transform: (T) -> R): List<R>
ints.map { value -> value * 2 }
Lambdas
fun <T, R> List<T>.map(transform: (T) -> R): List<R>
ints.map { value -> value * 2 }
Lambdas
fun <T, R> List<T>.map(transform: (T) -> R): List<R>
ints.map { it * 2 }
Inline functions
l.lock()
try {
foo()
}
finally {
l.unlock()
}
Inline functions
inline fun lock<T>(lock: Lock, body: () -> T): T {
// ...
}
Inline functions
inline fun lock<T>(lock: Lock, body: () -> T): T {
// ...
}
Inline functions
lock(l) { foo() }
Inline functions
fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? {
var p = parent
while (p != null && !clazz.isInstance(p)) {
p = p.parent
}
return p as T?
}
Inline functions
fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? {
var p = parent
while (p != null && !clazz.isInstance(p)) {
p = p.parent
}
return p as T?
}
Inline functions
treeNode.findParentOfType(MyTreeNode::class.java)
Inline functions
treeNode.findParentOfType(MyTreeNode::class.java)
treeNode.findParentOfType<MyTreeNode>()
Inline functions
fun <T> TreeNode.findParentOfType(clazz: Class<T>): T?
Inline functions
inline fun <T> TreeNode.findParentOfType(clazz: Class<T>): T?
Inline functions
inline fun <reified T> TreeNode.findParentOfType(clazz: Class<T>): T?
Inline functions
inline fun <reified T> TreeNode.findParentOfType(): T?
fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? {
var p = parent
while (p != null && !clazz.isInstance(p)) {
p = p.parent
}
return p as T?
}
Inline functions
inline fun <reified T> TreeNode.findParentOfType(): T? {
var p = parent
while (p != null && p !is T) {
p = p.parent
}
return p as T?
}
Other
? Function in?x notation

? Operators overloading

? Tail recursion optimizations

? Local functions
Standart library
apply
inline fun <T> T.apply(block: T.() -> Unit): T {
block();
return this
}
apply
val args = Bundle(3)
args.putCharSequence(ARG_TITLE, title)
args.putCharSequence(ARG_MESSAGE, message)
args.putBoolean(ARG_CANCELABLE, cancelable)
val fragment = ProgressDialogFragment()
fragment.arguments = args
apply
val args = Bundle(3).apply {
putCharSequence(ARG_TITLE, title)
putCharSequence(ARG_MESSAGE, message)
putBoolean(ARG_CANCELABLE, cancelable)
}
val fragment = ProgressDialogFragment()
fragment.arguments = args
apply
val fragment = ProgressDialogFragment()
fragment.arguments = Bundle(3).apply {
putCharSequence(ARG_TITLE, title)
putCharSequence(ARG_MESSAGE, message)
putBoolean(ARG_CANCELABLE, cancelable)
}
apply
ProgressDialogFragment().apply {
arguments = Bundle(3).apply {
putCharSequence(ARG_TITLE, title)
putCharSequence(ARG_MESSAGE, message)
putBoolean(ARG_CANCELABLE, cancelable)
}
}
Functions
inline fun <T> T.apply(block: T.() -> 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)
also
ProgressDialogFragment().also { fragment ->
fragment.arguments = Bundle(3).also { args ->
args.putCharSequence(ARG_TITLE, title)
args.putCharSequence(ARG_MESSAGE, message)
args.putBoolean(ARG_CANCELABLE, cancelable)
}
}
also
ProgressDialogFragment().also { fragment ->
fragment.arguments = Bundle(3).also { args ->
args.putCharSequence(ARG_TITLE, title)
args.putCharSequence(ARG_MESSAGE, message)
args.putBoolean(ARG_CANCELABLE, cancelable)
}
}
let
Bundle(3).let { args ->
args.putCharSequence(ARG_TITLE, title)
args.putCharSequence(ARG_MESSAGE, message)
args.putBoolean(ARG_CANCELABLE, cancelable)
ProgressDialogFragment().apply { arguments = args }
}
let
Bundle(3).let { args ->
args.putCharSequence(ARG_TITLE, title)
args.putCharSequence(ARG_MESSAGE, message)
args.putBoolean(ARG_CANCELABLE, cancelable)
ProgressDialogFragment().apply { arguments = args }
}
let
Bundle(3).let { args ->
args.putCharSequence(ARG_TITLE, title)
args.putCharSequence(ARG_MESSAGE, message)
args.putBoolean(ARG_CANCELABLE, cancelable)
ProgressDialogFragment().apply { arguments = args }
}
Try-with-resource
val stream: InputStream = ¡­
stream.use {
it.read()
}
Try-with-resource
val stream: InputStream = ¡­
stream.use {
it.read()
}
@Deprecated
public annotation class Deprecated(
val message: String,
val replaceWith: ReplaceWith = ReplaceWith(""),
val level: DeprecationLevel = DeprecationLevel.WARNING
)
public annotation class ReplaceWith(
val expression: String, vararg val imports: String)
public enum class DeprecationLevel {
WARNING,ERROR,HIDDEN
}
Collections
devices.filter { it.cpu == "Qualcomm" }
.filter(Device::isLargeRamDevice)
.map { it.name }
.toList()
Collections
devices.asSequence()
.filter { it.cpu == "Qualcomm" }
.filter(Device::isLargeRamDevice)
.map { it.name }
.toList()
Collections
devices.asSequence()
.filter { it.cpu == "Qualcomm" }
.filter(Device::isLargeRamDevice)
.map { it.name }
.toList()
Java Difference
Common
? No ternary operator (?:)

? No static members

? No checked exception

? No ¡°switch¡± operator

? Declaration of array type

? Arrays in Kotlin are invariant

? No primitive types
Generics
? No raw types

? Declaration-site & User-site variances instead of wildcards

? Only upper bound constraint
Classes
? All classes are ?nal by default

? No ?elds

? All functions & properties are ?nal by default

? Nested classes has no access to outer class by default

? Outer class has no access to inner class private members

? No anonymous classes
Visibility Modi?ers
? ¡°Visibility modi?ers¡± instead of¡°Access modi?ers¡±

? All members are public by default

? No ¡°package private¡±

? New ¡°internal¡± visibility modi?er
Thanks!

More Related Content

Kotlin Advanced - Apalon Kotlin Sprint Part 3