var neverNull: String = "something" var mightBeNull: String? = null // "?" indicates this can be null if (neverNull.length > 0) { // This is OK … } if (mightBeNull.length > 0) { // Compiler catches this error for you … }Named parameters and default arguments
fun orderPizza(size: Size, pepperoni: Boolean, mushrooms: Boolean, ham: Boolean, pineapple: Boolean, pickles: Boolean, sausage: Boolean, peppers: Boolean, onion: Boolean) { ... } // Wait… did I just order pickles on my pizza? // Why do we even have that option? orderPizza(Size.LARGE, true, false, false, false, true, false, true, false)Compare that to a similar scenario using named parameters and default arguments:
fun orderPizza(size: Size, pepperoni: Boolean = false, mushrooms: Boolean = false, ham: Boolean = false, pineapple: Boolean = false, pickles: Boolean = false, sausage: Boolean = false, peppers: Boolean = false, onion: Boolean = false) { ... } orderPizza(Size.LARGE, ham = true, mushrooms = true)In addition to helping to avoid tragic pizza outcomes, this is much easier to read. It also reduces the number of variants of overloaded functions you need to write.
// Please don't put this in your app! when { password.equals("password") -> println("Insecure password!") password.length < 4 -> println("Too short!") else -> { println("Secure password!") } }Smart Casts
if (obj is String) { // Compiler casts obj to a String for you. // (Would work with && instead of nested ifs too.) if (obj.length > 0) { … } }This generalizes to the when statement as well:
// Assume reasonable implementations of Cat and Dog when (obj) { is Cat -> obj.meow(...) is Dog -> obj.woof(...) else -> { … } }Extension functions
toPigLatin
method, you can now add it yourself without having to create a new helper class to wrap String or going through the trouble of serving on a language committee:
// The "String." prefix indicates that this method should // extend the existing String class fun String.toPigLatin() : String { ... } val plainOldString : String = "some text" // Can now call toPigLatin as if were a method on String println(plainOldString.toPigLatin()) // Or: println("some text".toPigLatin())Destructuring Declarations
data class Order(val itemCode: String, val quantity: Int, val price: Float)A function that uses one of these classes as the return type is very close to supporting multiple return values:
fun getOrder(...): Order { ... return Order(itemCode, quantity, price); }To get all the way there, you can use the destructuring declaration syntax. The following statement takes the
Order
object, extracts its three properties, and then assigns them to the three variables what
, howMany
and howMuch
— all courtesy of the Kotlin compiler, which also infers the correct types for you.
val (what, howMany, howMuch) = getOrder(...)Lambdas
fun allStrings(collection: Collection)= collection.all { it is String }That lambda syntax is building block of one of Kotlin's coolest features: the ability to create builders that use JSON-like syntax that also happens to be syntactically valid Kotlin. This example is adapted from an extended discussion here, but you can get the flavor of what it possible with this snippet:
fun generatePage(withEmphasis : Boolean) { val result = html { head { title { +"Kotlin Builders" } } body { h1 { +"Kotlin Builders" } p { +"This is " if (withEmphasis) b { +"really " } +"interesting" a(href = "https://goo.gl/rHwJio") { +"More here" } } } } println(result) }There are a couple of interesting things going on here. First, this shows how expressive Kotlin's functional syntax can be: in this example, "
html
", "head
", "body
, etc. are all just functions written in Kotlin and the stuff in curly braces that follows are functional parameters. (This snippet uses functions with names that match HTML tags to build a representation of a web page, but of course you can use this pattern to build any complex data structure with whatever names you want.) The second interesting thing is the "withEmphasis
" conditional. This may look like we are mixing code (if (withEmphasis)
…) with data (all the HTML-esque tags), but the "data" here is actually just more code. Since it is all really just code, this lets you build complex data structures using a declarative syntax while also having inline access to the full capabilities of the Kotlin language.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3