// file: Beaut.kt
data class Lunch(val bread: String, val topping: String)
val yumyum = Lunch("Toast", "Avocado")
fun main(args: Array<String>){
val buyHouse: (Lunch) -> Unit = {
val (_, topping) = it
when(topping){
"Avocado" -> println("Not a chance")
else -> println("Hmmm... still probably no")
}
}
buyHouse(yumyum)
}
// Not a chance
var str: String = "Text"
val str = "String"
fun sideEffects() {
println("Returning Unit -> no need for type")
}
fun expressiveFunc() = "Return type String, as is known"
fun explicit(): String {
return "Making the return type explicit"
}
public class Interop {
public static void main(String[] args) {
final Lunch lunch = BeautKt.getYumyum();
System.out.println("I had "
+ lunch.getTopping()
+ " on "
+ lunch.getBread()
+ " for lunch.");
}
}
// I had avocado on toast for lunch.
public String doSomething(String arg1, String arg2, ...){ if (arg1 == null) { throw new IllegalArgumentException("arg1 == null"); } if (arg2 == null) { throw new IllegalArgumentException("arg1 == null"); } // Etc // Finally do something }
java.lang.nullPointerException at com.something.doSomething(Something.java:42) at com.someframework.doThatThing(ThingDoer.java:13) at org.application.service.letsHopeThisWorks(HopeBuildsSoftware.java:666) ... ...s
class TopShelf(val drinks: List<String>?)
fun main(args: Array<String>){
val monday = TopShelf(null)
println(monday.drinks.get(0))
}
/*
* Error Kotlin: Only safe (?.) or non-null asserted (!!.)
* calls are allowed on a nullable receiver of type List<String>?
*/
println(monday.drinks?.get(0)) // This is grand
// null
class EmptyClass
interface MarkerInterface
class WithConstructor(val value: String): MarkerInterface
class WithMembers(val value: String) {
fun doFun() = "Fun!"
}
object Singleton {
val staticity = "Not Quite, but close"
}
class Companied {
companion object {
val truly = "Static, truly static"
}
} // Companied.truly
object initialized{
val thing: String
init {
thing = "Hello"
}
}
class LateBloomer{
lateinit var thang: String
fun doTheInit(str: String){
thang = str
}
@Autowired
lateinit var thong: String
@Inject
lateinit var gString: String
}
data class Covfefe(val first: String, val second: String)
data class -> toString, equals, hashCode, copy
val (america, finland) = Covfefe("America", "Finland")
public final class Covfefe {
@NotNull
private final String first;
@NotNull
private final String second;
@NotNull
public final String getFirst() {
return this.first;
}
@NotNull
public final String getSecond() {
return this.second;
}
public Covfefe(@NotNull String first, @NotNull String second) {
Intrinsics.checkParameterIsNotNull(first, "first");
Intrinsics.checkParameterIsNotNull(second, "second");
super();
this.first = first;
this.second = second;
}
@NotNull
public final String component1() {
return this.first;
}
@NotNull
public final String component2() {
return this.second;
}
@NotNull
public final Covfefe copy(@NotNull String first, @NotNull String second) {
Intrinsics.checkParameterIsNotNull(first, "first");
Intrinsics.checkParameterIsNotNull(second, "second");
return new Covfefe(first, second);
}
public String toString() {
return "Covfefe(first=" + this.first + ", second=" + this.second + ")";
}
public int hashCode() {
return (this.first != null?this.first.hashCode():0) * 31 + (this.second != null?this.second.hashCode():0);
}
public boolean equals(Object var1) {
if(this != var1) {
if(var1 instanceof Covfefe) {
Covfefe var2 = (Covfefe)var1;
if(Intrinsics.areEqual(this.first, var2.first) && Intrinsics.areEqual(this.second, var2.second)) {
return true;
}
}
return false;
} else {
return true;
}
}
}
sealed class NextBigThing
data class PiperChat(val pakistaniDenzel: String): NextBigThing()
data class PiedPiper(val weissmanScore: String): NextBigThing()
val matchable: NextBigThing = fetchBigThing()
when(matchable){
is PiperChat -> println("Creepy Videochat")
is PiedPiper -> println("New Internet")
else -> println("nope")
}
val drivingForce = when(matchable){
is PiperChat -> matchable.pakistaniDenzel
is PiedPiper -> matchable.weissmanScore
}
val carDoors = if(matchable is PiperChat) {
"--(ツ)--"
} else {
"¯\\_(ツ)_/¯"
}
val payingRent = try {
askJinYang()
} catch (ex: InsultException){
// Swallow ex
"aFat and aPoor"
}
val funType: (num: Int) -> Int = {num -> num * num}
val funType2: (Int) -> Int = {it * it}
val funfunType: (Int, (Int) -> Int) -> Int = { num, func ->
func(num) * func(num)
}
inline fun <S, reified T> inliner(other: S, typed: T) {
if (other is T) {
print("Same Types")
}
}
data class PiperChat(val pakistaniDenzel: String): NextBigThing() {
operator fun plus(internet: PiedPiper) = when(pakistaniDenzel){
"fired" -> internet
else -> this
}
}
sealed class NextBigThing {
infix fun until(num: Int) = when(this) {
is PiedPiper -> weissmanScore.toInt() - num
is PiperChat -> 2 - num
}
}
val games = PiedPiper("23")
var eye = 2
val `fun` = PiperChat("Dinesh")
val scoreOrEyeCount: Int = `fun` + games until --eye
val lamdba = { arg: Int ->
arg * arg
}
/* val lambda = */ {it: Int -> it * it }
fun macbook(func: () -> Unit) = func()
macbook({ println("trash") })
macbook{ println("trash") }
fun isTrashbook(make: Int, func: (Int) -> Boolean): Boolean =
func(make)
val isTrash = isTrashbook(2016) {
it == 2016
}
fun String.uberized() = this + ", bro"
println("what's up".uberized()) // what's up, bro
fun String?.uberized() = (this ?: "No way") + ", mo"
val str: String? = null
println(str.uberized()) // No way, mo
val String.fine: String
get() = "a dumpster fire"
fun String.`is`(situation: String) = this + "is $fine"
println("uber".`is`("".fine)) // uber is a dumpster fire
From stdLib
fun <T, R> T.let(f: (T) -> R): R = f(this)
// nullableVar?.let { print(it.someValue) }
fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
// javaBean.apply { this.beanField1 = "First field" }
fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
// with(imperativo) { dothis() doThat() }
fun <T, R> T.run(f: T.() -> R): R = f()
// "str".run { this + "otherStr" }
fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
// javaBean.also { it.beanField2 = "Second Field" }
Scaffolding
data class Pizza(val name: String,
var toppings: List<Topping> = emptyList(),
val price: Int = 0)
interface Topping {
val name: String
val unitPrice: Int
}
abstract class BaseTopping(override val name: String,
override val unitPrice: Int = 0): Topping {
var amount: Int = 0
operator fun plus(that: Topping): List<Topping> =
listOf(this, that)
}
Scaffolding
class Cheese: BaseTopping("Cheese") {
override val unitPrice: Int
get() = 3
}
class Ananas: Topping("Ananas"){
override val unitPrice = 4
}
class Anchovy: Topping("Anchovy"){
override val unitPrice = 6
}
Construction
fun Pizza.`with`(topper: () -> List<Topping>): Pizza =
apply { toppings = topper() }
infix fun Int.of(topping: BaseTopping): BaseTopping =
topping.also { it.amount = this }
fun order(name: String, hoef: Pizza.() -> Pizza) =
Pizza(name).hoef()
fun main(args: Array<String>) {
order("Kotlinante") { // (name, Pizza.() -> Pizza) -> Pizza
`with` { // this == our Kotlinante pizza
(3 of Cheese()) +
(2 of Anchovy()) +
(2 of Ananas())
// listOf(Cheese(amount=3), Anchovy(amt=2), Ananas(amt=2))
}
}
}
// Pizza(name=Kotlinante, toppings=[Cheese@279f2327,
// Anchovy@2ff4acd0, Ananas@54bedef2], price=0)
class Sloth {
val timeToSleep: Boolean by lazy {
println("Always")
true
}
}
class NosyNeighbour {
var shoppingTrip: Groceries by observable(Groceries()) {
_, previousGroceries: Groceries, newGroceries: Groceries ->
println("""Again he bought more craft beer.
I believe he is a beer connoisseur, not an alcoholic.""")
} // property: KProperty<*>
}
class Wifey {
var shoppingTrip: Groceries by vetoable(Groceries()) {
_, previousGroceries: Groceries, newGroceries: Groceries ->
!newGroceries.containsBeer()
}
}
Properties
data class Pizza(val name: String,
var toppings: List<Topping> = emptyList()) {
val price: Int by PriceCalculator()
override fun toString() =
"name=$name, price=$price, toppings=$toppings"
}
class PriceCalculator : ReadOnlyProperty<Pizza, Int> {
override fun getValue(thisRef: Pizza, property: KProperty<*>) =
thisRef.toppings.fold(0) { acc, it ->
acc + it.unitPrice
}
}
// Pizza(name=Kotlinante, toppings=[Cheese@3caeaf62,
// Anchovy@e6ea0c6, Ananas@6a38e57f], price=13)
Classes
interface Topping {
val name: String
val unitPrice: Int
}
abstract class BaseTopping(val priceProvider: Topping)
: Topping by priceProvider {
var amount: Int = 0
operator fun plus(that: Topping): List<Topping> =
listOf(this, that)
override fun toString() =
"{name=$name, price=$unitPrice, amount=$amount}"
}
class PriceAndNameProvider(override val name: String,
override val unitPrice: Int): Topping
class Cheese : BaseTopping(PriceAndNameProvider("Cheese", 3))
class Ananas : BaseTopping(PriceAndNameProvider("Ananas", 4))
class Anchovy : BaseTopping(PriceAndNameProvider("Anchovy", 6))
val BaseTopping.price: Int
get() = unitPrice * amount
// { acc, it ->
// acc + (it as BaseTopping).price
// }
fun main(args: Array<String>) {
order("Kotlinante") {
`with` {
(3 of Cheese()) +
(2 of Anchovy()) +
(2 of Ananas())
}
}
}
// name=Kotlinante, price=29, toppings=
// [{name=Cheese, price=3, amount=3},
// {name=Anchovy, price=6, amount=2},
// {name=Ananas, price=4, amount=2}]
All already familiar frameworks work out of the box.
Many frameworks!
The Compiler helps us a lot more than in Java.
Safe like a wall!
It just works.
There is no need to rewrite anything, existing codebase can remain untouched and
adding it to a project is literally a three click operation.
Cheap!
If you know Java, you'll learn Kotlin in few days, guaranteed.
So easy!
Once you go Kotlin,
your fun will be Dublin