Share
Embed
Transcript
78 slides
-
Kotlin? • Statically Typed • Developed by JetBrains • 100%
interoperable with Java -
Why Kotlin? • Mutability problems • General verbosity • No
control over platform types -
Nullability I call it my billion-dollar mistake. It was the
invention of the null reference in 1965 […] This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. -
Why Kotlin? • Type inference • Lambdas • Null safety
• Smart casts • String templates • Higher order functions • Extension functions • Data classes • Default Values -
Getting Started buildscript { repositories { mavenCentral() } dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.3" } } apply plugin: 'kotlin' dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3" } -
Getting Started buildscript { repositories { mavenCentral() } dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.3" } } apply plugin: 'kotlin' dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3" } -
fun sum(a: Int, b: Int): Int { return a +
b } Syntax -
fun sum(a: Int, b: Int): Int { return a +
b } Syntax -
fun sum(a: Int, b: Int): Int { return a +
b } Syntax -
Defining Variables val a: Int = 1 val b =
1 var x = 5 x += 1 final int a = 1; int x = 5; -
Defining Variables val a: Int = 1 val b =
1 var x = 5 x += 1 final int a = 1; int x = 5; -
Properties public class Person { private String name;
public String getName() { return name; } public void setName(String name) { this.name = name; } } -
Properties var person = Person() person.name = "Mike" val name
= person.name class Person { var name: String = "Ryan" } -
String Templates var person = Person("Mike") println("Hello my name
is ${person.name}") -
val string: String = "Mike" val another: String = null
// does not compile val nullable: String? = null // ok Nullability -
Nullability println(person?.name) val email = data["email"] ?: "[email protected]"
data?.let { // execute this block if not null println(files!!.size) -
Nullability println(person?.name?.length) val email = data["email"] ?: "[email protected]"
data?.let { // execute this block if not null println(files!!.size) -
Nullability println(person?.name?.length) val email = data["email"] ?: "[email protected]"
data?.let { // execute this block if not null println(files!!.size) -
fun toast(message: String, length: Int = Toast.LENGTH_SHORT) { Toast.makeText(this, message,
length).show() } Default Values -
fun toast(message: String, length: Int = Toast.LENGTH_SHORT) { Toast.makeText(this, message,
length).show() } toast("Hello") toast("Hello", Toast.LENGTH_LONG) toast("Hello", length = Toast.LENGTH_LONG) Default Values -
Extension Functions fun List.swap(index1: Int, index2: Int) { val tmp
= this[index1] this[index1] = this[index2] this[index2] = tmp } -
fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) { Toast.makeText(this, message,
duration).show() } fun List.swap(index1: Int, index2: Int) { val tmp = this[index1] this[index1] = this[index2] this[index2] = tmp } Extension Functions -
{ it.isEmpty() } { it.length == 10 }
{ isPalindrome(it) } Function Expressions -
{ it.isEmpty() } { it.length == 10 }
{ isPalindrome(it) } Function Expressions -
{ it.isEmpty() } { it.length == 10 }
{ isPalindrome(it) } Function Expressions -
val isEmpty: (String) -> Boolean = { it.isEmpty() }
val exactly10: (String) -> Boolean = { it.length == 10 } val palindrome: (String) -> Boolean = { isPalindrome(it) } Function Expressions -
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> { // ...
} Higher order functions -
Higher order functions fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>
{ val newList = ArrayList<T>() for (item in this) { if(predicate(item)) { newList.add(item) } } return newList } -
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> { // ...
} Higher order functions val names = listOf("Mike", "John", "Bob") names.filter { it == "Mike" } // ["Mike"] names.filter(palindrome) // ["Bob"] -
inline fun supportsLollipop(code: () -> Unit) { if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.LOLLIPOP) { code.invoke() } } Inline Functions -
supportsLollipop { getWindow().setStatusBarColor(Color.BLACK) } inline fun supportsLollipop(code: () -> Unit)
{ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { code.invoke() } } Inline Functions -
public class ContactsAdapter extends RecyclerView.Adapter { interface ContactClickListener { void
onContactClicked(Contact contact); } -
public class ContactsAdapter extends RecyclerView.Adapter { interface ContactClickListener { void
onContactClicked(Contact contact); } recycler.setAdapter(new ContactsAdapter(contacts, new ContactsAdapter.ContactClickListener() { @Override public void onContactClicked(ContactsAdapter.Contact contact) { } })); -
recycler.adapter = ContactsAdapter(contacts) { navigateToDetail(it) } class ContactsAdapter(val contacts:
List<Contact>, val listener: (Contact) -> Unit) itemView.setOnClickListener { listener(contact) } -
recycler.adapter = ContactsAdapter(contacts) { navigateToDetail(it) } class ContactsAdapter(val contacts:
List<Contact>, val listener: (Contact) -> Unit) itemView.setOnClickListener { listener(contact) } -
recycler.adapter = ContactsAdapter(contacts) { navigateToDetail(it) } class ContactsAdapter(val contacts:
List<Contact>, val listener: (Contact) -> Unit) itemView.setOnClickListener { listener(contact) } -
inline fun SharedPreferences.edit( func: SharedPreferences.Editor.() -> Unit) { val editor
= edit() editor.func() editor.apply() } Extension Function Expressions -
inline fun SharedPreferences.edit( func: SharedPreferences.Editor.() -> Unit) { val editor
= edit() editor.func() editor.apply() } preferences.edit { putString("foo", "bar") putString("fizz", "buzz") remove("username") } Extension Function Expressions -
inline fun SharedPreferences.edit( func: SharedPreferences.Editor.() -> Unit) { val editor
= edit() editor.func() editor.apply() } fun SharedPreferences.Editor.set(pair: Pair<String, String>) = putString(pair.first, pair.second) Extension Function Expressions -
preferences.edit { set("foo" to "bar") set("fizz" to "buzz") remove("username") }
Extension Function Expressions -
verticalLayout { padding = dip(30) editText { hint = "Name"
textSize = 24f } editText { hint = "Password" textSize = 24f } button("Login") { textSize = 26f } } Anko -
Java Interoperability class Person { private String name; public
void setName(String name) { this.name = name; } } -
var person = Person() person.name = "name" Java Interoperability class
Person { private String name; public void setName(String name) { this.name = name; } } -
// com/example/util/DateExtensions.kt fun Date.isTuesday() = day == 2 //
com/example/util/DateExtensionsKt.java static boolean isTuesday(Date date) { return date.getDay() == 2; } Java Interoperability - Extensions -
// com/example/util/DateExtensions.kt fun Date.isTuesday() = day == 2 //
com/example/util/DateExtensionsKt.java static boolean isTuesday(Date date) { return date.getDay() == 2; } Java Interoperability - Extensions -
// com/example/util/DateExtensions.kt @file:JvmName("DateUtils") fun Date.isTuesday() = day == 2
// com/example/util/DateUtils.java static boolean isTuesday(Date date) { return date.getDay() == 2; } Java Interoperability - Extensions -
Data Classes class Person { private String name; private int
age; public String getName() { return name; } public int getAge() { return age; } } -
Data Classes @Override public boolean equals(Object o) { if (this
== o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (age != person.age) return false; return name != null ? name.equals(person.name) : person.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } @Override public String toString() { return super.toString(); } }