Created
February 22, 2016 22:10
-
-
Save jacobmoncur/2f58d11c9a8a029fa98c to your computer and use it in GitHub Desktop.
Kotlin Brown Bag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Kotlin! (kotlinlang.org) | |
// Kotlin is... | |
// A Statically typed programming language | |
// for the JVM, | |
// Android | |
// and the browser | |
// Kotlin is... | |
// Simple, Concise, Expressive, Safe | |
/***** Variables ******/ | |
val firstName: String = "Luke" | |
val lastName = "Skywalker" // `String` type is inferred | |
val immutableInt = 20 // `val` is immutable | |
var mutableInt = 55 // `var` is mutable | |
/***** Functions ******/ | |
fun sum(a: Int, b: Int): Int { | |
return a + b | |
} | |
// Same function with an | |
// expression body and inferred return type | |
fun sum(a: Int, b: Int) = a + b | |
fun createJedi(name: String, saberColor: Int = Color.GREEN): Jedi { | |
... | |
} | |
createJedi("Yoda") // uses default param for saberColor | |
createJedi("Kylo Ren", Color.RED) | |
createJedi(saberColor = Color.BLUE, name = "Rey") // Named params! | |
/***** Types ******/ | |
val string: String = "Hello" | |
val int: Int = 1 | |
val float: Float = 1.f | |
val double: Double = 1.0 | |
... | |
// Nullables (Safety!) | |
var a: String = "Alderaan" | |
a = null // Compilation error | |
a.length // OK | |
// Nullable Type (?) | |
var b: String? = "Tatooine" | |
b = null // OK | |
b.length // Compilation error: `b` could be null | |
b?.length // OK: Safe operator call on length | |
// Optional listener | |
listener?.notify() | |
// `elvis operator` ?: allows for default value | |
val likeCount = comment?.likes ?: 0 | |
val user: User? = User() | |
// Smart Cast | |
if(user != null) { | |
user.foo() // compiler knows user isn't null, `?` isn't needed | |
} else { | |
} | |
// if-let | |
user?.let { | |
it.foo() | |
} | |
/***** String templates ******/ | |
val name = "Kylo" | |
var message = "Hello my name is $name" | |
val jedi = Jedi() | |
val message = "I have ${ jedi.computePower() } jedi power points." | |
/***** Classes ******/ | |
class Person(val firstName: String) { | |
} | |
// Extends User | |
class Person(val firstName: String): User { | |
} | |
// Extends User, implements Listener | |
class Person(val firstName: String): User, Listener { | |
} | |
// `data` gives equals(), hashCode(), toString(), copy() for free! | |
data class Person(val firstName: String) | |
/***** Singletons (Objects) ******/ | |
// Thread safe, simple declaration | |
object DeathStar { | |
val deathRay = DeathRay() | |
val passengers = 10000 | |
fun destroyPlanet(planet: Planet) { | |
// Kaboom! | |
deathRay.shoot(planet) | |
} | |
} | |
DeathStar.destroyPlanet(Earth()) | |
/***** Operator overloading ******/ | |
a + b ---> a.plus(b) | |
/***** Ranges ******/ | |
for (i in 1..4) print(i) // prints "1234" | |
/***** Lambdas (Function literals, Closures) ******/ | |
// Function Types | |
val sum: (Int, Int) -> Int = { x, y -> x + y } | |
val sum = { x: Int, y: Int -> x + y } | |
val result = sum(1, 1) // 2 | |
// Funtion Literals | |
list.filter { it > 0 } // '(it: Int) -> Boolean' | |
// Higher Order Function (Takes function as an input) | |
fun doSomethingAmazing(input: String, done: (String) -> Unit) { | |
done("Amazing: $input") | |
} | |
// Simple API for async operations | |
fun upload(value: String, done: (res: Response?, err: Error?) -> Unit) { | |
// Do something amazing and async... | |
asyncOperation { | |
done(response, error) | |
} | |
} | |
// Java | |
List<String> list = Arrays.asList("1", "2", "3", "4"); | |
Integer maxValue = null; | |
for(String item : list){ | |
Integer value = Integer.parseInt(item); | |
Integer doubledValue = value * 2; | |
if(doubledValue < 6) { | |
if(maxValue == null){ | |
maxValue = doubledValue; | |
} else { | |
maxValue = (doubledValue > maxValue) ? doubledValue : maxValue; | |
} | |
} | |
} | |
// Kotlin | |
val list = listOf("1", "2", "3", "4") | |
val max = list.map { it.toInt() * 2 } .filter { it < 6 } .max() | |
/***** Extension Functions ******/ | |
// Add functionality to existing types | |
fun String.toURI(): Uri { | |
return Uri.parse(this) | |
} | |
val uri = "http://www.google.com".toURI() | |
fun Double.clamp(min: Double, max: Double): Double { | |
return Math.max(min, Math.min(max, this)) | |
} | |
val percentage = 1.5 | |
val clamped = percentage.clamp(0.0, 1.0) // 1.0 | |
// If there is an API/SDK that is too verbose | |
// or you just don't like it, CHANGE IT | |
/***** Delegate Properties ******/ | |
// Only allocates `lazyValue` when it is referenced | |
val lazyValue: String by lazy { | |
"Hello" | |
} | |
// Prints a the change each time counter is updated | |
var counter: Int by Delegates.observable(0) { prop, old, new -> | |
println("$old -> $new") | |
} | |
// Only sets username to new value if it is not empty | |
var username: String by Delegates.vetoable("None") { prop, oldName, newName -> | |
newName.isNotEmpty() | |
} | |
// Custom Delegate Properties | |
var rememberPin: Boolean by Cacheable("rememberPin", false) | |
// Dependency Injection | |
val mongoTemplate: MongoTemplate by Injector() | |
/***** When Statement ******/ | |
// `when` == switch + AWESOME | |
when(currentButtonState){ | |
ButtonState.GONE -> setupGoneButton(duration) | |
ButtonState.BEGIN -> setupStartButton(duration) | |
ButtonState.PROGRESS -> setupProgress() | |
ButtonState.SUCCESS -> setupSuccessButton() | |
} | |
val iconId = when { | |
link.contains("twitter", true) -> R.drawable.twitter | |
link.contains("facebook", true) -> R.drawable.facebook | |
link.contains("linkedin", true) -> R.drawable.linkedin | |
link.contains("pinterest", true) -> R.drawable.pinterest | |
link.contains("skype", true) -> R.drawable.skype | |
else -> R.drawable.blank | |
} | |
when (x) { | |
in 1..10 -> print("x is in the range") | |
in validNumbers -> print("x is valid") | |
!in 10..20 -> print("x is outside the range") | |
else -> print("none of the above") | |
} | |
// `when` as function statement | |
fun transform(color: String) = when (color) { | |
"Red" -> Color.RED | |
"Green" -> Color.GREEN | |
"Blue" -> Color.BLUE | |
else -> Color.TRANSPARENT | |
} | |
// Instance type checking | |
val message: Any = messages.get(position) | |
when(message) { | |
is ReceiptMessage -> print("ReceiptMessage") | |
is PaymentMessage -> print("ProvisioningMessage") | |
is ErrorMessage -> print("ErrorMessage") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment