Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Help Kotlin Help You

Caren
August 13, 2019

Help Kotlin Help You

Caren

August 13, 2019
Tweet

More Decks by Caren

Other Decks in Education

Transcript

  1. public class User { private String name; @Nullable private String

    emailAddress; public User(String name) { … } public User(String name, String emailAddress) { … } public String getName() { … } public void setName(String name) { … } @Nullable public String getEmailAddress() { … } public void setEmailAddress(@Nullable String emailAddress) { … } @Override public String toString() { … } @Override public boolean equals(Object o) { … } @Override public int hashCode() { … } }
  2. public class User { private String name; @Nullable private String

    emailAddress; public User(String name) { … } public User(String name, String emailAddress) { … } public String getName() { … } public void setName(String name) { … } @Nullable public String getEmailAddress() { … } public void setEmailAddress(@Nullable String emailAddress) { … } @Override public String toString() { … } @Override public boolean equals(Object o) { … } @Override public int hashCode() { … } }
  3. • Maintaining data classes can be a hassle • Creating

    objects can be confusing if builder pattern doesn’t exist
 
 new Book("Jane Eyre", "Charlotte Brontë”);
  4. • Maintaining data classes can be a hassle • Creating

    objects can be confusing if builder pattern doesn’t exist
 
 new Book("Jane Eyre", "Charlotte Brontë”); ??? ???
  5. public class User { private String name; @Nullable private String

    emailAddress; public User(String name) { … } public User(String name, String emailAddress) { … } public String getName() { … } public void setName(String name) { … } @Nullable public String getEmailAddress() { … } public void setEmailAddress(@Nullable String emailAddress) { … } @Override public String toString() { … } @Override public boolean equals(Object o) { … } @Override public int hashCode() { … } }
  6. • Automatically creates equals() , hashCode(), toString()
 data class User

    (val name: String, var emailAddress: String? = null)
  7. • Automatically creates equals() , hashCode(), toString() • val vs

    var
 data class User (val name: String, var emailAddress: String? = null)
  8. • Automatically creates equals() , hashCode(), toString() • val vs

    var • denotes nullable fields
 
 val userDroid = User(name = "Droid")
 data class User (val name: String, var emailAddress: String? = null)
  9. • Automatically creates equals() , hashCode(), toString() • val vs

    var • denotes nullable fields
 
 val userDroid = User(name = "Droid") • default values
 data class User( val name: String, var emailAddress: String? = null, var optIntoEmails: Boolean = true )
  10. !! usually signals a code smell and is not as

    safe as you think be wary of silent failures using ? 

  11. !! usually signals a code smell and is not as

    safe as you think be wary of silent failures using ? 
 user?.paymentMethod?.executeTransaction()
  12. !! usually signals a code smell and is not as

    safe as you think be wary of silent failures using ? 
 user?.paymentMethod?.executeTransaction() ?: Log.i("TAG", “No payment method stored”)
  13. // Java-like if (userDroid.emailAddress != null && userDroid.optIntoEmails) { sendMarketingEmail(userDroid.emailAddress!!)

    } // Kotlin-esque userDroid.emailAddress?. takeIf { userDroid.optIntoEmails }?. let { sendMarketingEmail(it) }
  14. Functions that allow for changing ‘scope’ of variables user?.fullName?.let {

    fullName -> val formattedName = format(fullName) displayGreeting(formattedName) } Scope Functions
  15. Functions that allow for changing ‘scope’ of variables also {

    } apply { } let { } run { } with("an argument") { doSomething(this) } Similar in functionality, differences in appropriate use case Scope Functions
  16. if (user != null && user.emailAddress != null) { sendMarketingEmail(user.emailAddress!!)

    } user?.emailAddress?.let { sendMarketingEmail(it) } let { }
  17. if (user != null && user.emailAddress != null) { sendMarketingEmail(user.emailAddress!!)

    } user?.emailAddress?.let { sendMarketingEmail(it) } user?.emailAddress?.let { emailAddress -> sendMarketingEmail(emailAddress) } let { }
  18. if (user != null && user.emailAddress != null) { sendMarketingEmail(user.emailAddress!!)

    } user?.emailAddress?.let { sendMarketingEmail(it) } user?.emailAddress?.let { emailAddress -> sendMarketingEmail(emailAddress) } Database.getConnection().let { } // connection doesn't exist outside let { }
  19. val view = View(this).apply { setBackgroundColor() setOnLongClickListener { } setOnClickListener

    { } } val view2 = View(this) view2.setBackgroundColor() view2.setOnLongClickListener { } view2.setOnLongClickListener { } apply { }
  20. also { } Useful for calls that need a contextual

    object, but doesn’t alter the object itself
  21. also { } val paint = Paint() .apply { color

    = Color.BLUE pathEffect = PathEffect() } .also { print("Starting paint with ${it.color}") }
  22. run { } val randomWelcomeGreeting = GreetingGenerator.obtain().run { day =

    getDayOfWeek() mood = Mood.Cheerful voice = Voice.OPRAH generate() }
  23. Scope Functions let Executing code with null check 
 Introducing

    local variables apply Object configuration
 run Top level initialization also Additional effects with Grouping function calls
  24. Simplify managing background threads without managing callbacks Sequential code is

    a lot easier to read and manage
 
 // Async callbacks networkRequest { result -> // Successful network request databaseSave(result) { rows -> // Result saved } }
  25. Simplify managing background threads without managing callbacks Sequential code is

    a lot easier to read and manage
 
 // Async callbacks networkRequest { result -> // Successful network request databaseSave(result) { rows -> // Result saved } } // The same code with coroutines val result = networkRequest() // Successful network request databaseSave(result) // Result saved vs
  26. import kotlinx.android.synthetic.main. activity_main.*
 
 button.text = "Click me" <TextView 


    android:id="@+id/button"/> Activity.kt activity.xml Makes available ALL ids defined in the project
  27. import kotlinx.android.synthetic.main. activity_main.*
 
 button.text = "Click me" <TextView 


    android:id="@+id/button"/> Activity.kt activity.xml Makes available ALL ids defined in the project Views unrelated to inflated layout are accessible
  28. import kotlinx.android.synthetic.main. activity_main.*
 
 button.text = "Click me" <TextView 


    android:id="@+id/button"/> Activity.kt activity.xml Makes available ALL ids defined in the project Views unrelated to inflated layout are accessible Doesn’t expose nullability well
  29. import kotlinx.android.synthetic.main. activity_main.*
 
 button.text = "Click me" <TextView 


    android:id="@+id/button"/> Activity.kt activity.xml Makes available ALL ids defined in the project Views unrelated to inflated layout are accessible Doesn’t expose nullability well Other options: Data Binding or Butter Knife