Mejores prácticas de Kotlin

Kotlin, creado hace apenas 5 años, ha sido considerado el lenguaje de programación prioritario para Android desde 2019. Y, sin embargo, este lenguaje es bastante joven y continúa evolucionando, por lo que a veces no está claro cuál es la mejor manera de escribir el código. A menudo tenemos discusiones en nuestro equipo sobre el tema del código Kotlin puro, y sobre esa base hemos compilado nuestras mejores prácticas. Nos gustaría compartir estas recomendaciones y esperamos sus preguntas.





Bueno, ¡comencemos! En primer lugar, hay mucho azúcar sintáctico en Kotlin y, si se usa en exceso, resulta difícil leer dicho código. Los siguientes puntos se pueden atribuir a la lucha entre la brevedad y la legibilidad





No escriba una declaración de clase en una línea

– . .





class ChannelViewModel(
       val conversationId: String,
       getChannelUseCase: GetChannelUseCase,
) : ViewModel() {
      
      



, :





  • , ( Android Studio / Shift+Command+Up/Down)





  • .





return

:





data class MyClass(val number: Int, val flag: Boolean)

fun create(numberParam: Int?, flag: Boolean?): MyClass? {
   return MyClass(numberParam ?: return null, flag == true)
}
      
      



return, , . , numberParam null,  return MyClass(...) return null. if, :





fun create(numberParam: Int?, flag: Boolean?): MyClass? {
   if (numberParam == null) {
       return null
   }
   return MyClass(numberParam, flag == true)
}
      
      



it

, it , - :





values?.filterNot { selectedValues?.contains(it) == true }
   ?.let {
       selectedValues?.addAll(it)
       result[key]?.values = selectedValues?.filter { it.isChecked }
   }
      
      



let:





values?.filterNot { allSelectedValues?.contains(it) == true }
   ?.let { newValues ->
       allSelectedValues?.addAll(newValues)
       result[key]?.values = allSelectedValues?.filter { it.isChecked }
   }
      
      



it – . -null, . :





val newValues = values.filterNot { selectedValues.contains(it) }
selectedValues.addAll(newValues)
result[key]?.values = selectedValues.filter { it.isChecked }
      
      



?. -null

:






private var animatedView: FrameLayout? = null
...
animatedView?.animate()?.alpha(1f)?.setDuration(500)?.interpolator = AccelerateInterpolator()
      
      



null , animatedView null. if (animatedView != null) . ,   animatedView null. lateinit , null:





private lateinit var animatedView: FrameLayout
...
animatedView.animate().alpha(1f).setDuration(500).interpolator = AccelerateInterpolator()
      
      



Java Kotlin, “ ”. . Java - if when, (let, apply, also, with, run), , Utils extension .





!!

!! , NullPointerException, !! “”. 





!! : 





  • -null ( lateinit animatedView)





  • let ?.let { … }





  • - ?:





  • , , , null, checkNotNull requireNotNull. : IllegalStateException IllegalArgumentException . 





, !! Java Kotlin, @NonNull Java-.





when if

:





val price = if (priceData.isWeightPrice) {
   priceData.minDiscountPrice.toInt()
} else if (priceData.discountPrice != 0.0) {
   priceData.discountPrice.toInt()
} else {
   priceData.price.toInt()
}
      
      



when:





val price = when {
   priceData.isWeightPrice -> priceData.minDiscountPrice.toInt()
   priceData.discountPrice != 0.0 -> priceData.discountPrice.toInt()
   else -> priceData.price.toInt()
}
      
      



when , , . 





when , . , when .





Util

- , extension. . 





, . , , .





, Util Kotlin ( : Java , Kotlin – ). - , (package) . (extension , , ; , - ). , , , .





, ( “ ”). , .





(trailing commas) 

1.4. ( ) : diff . 





Single Abstract Method interface (Fun interface)

Kotlin 1.4.0. , fun :





this.actionClickListener = object : BubbleView.ClickListener {
   override fun onBubbleViewClick() {
           ...
       }
   }
      
      







 this.actionClickListener = BubbleView.ClickListener {
      ...
  }
      
      



 fun:





fun interface ClickListener {
   fun onBubbleViewClick()
}
      
      



, Java, Kotlin , SAM- . :





  • (T) -> R;





  • , SAM-;





  • , . 





Kotlin , , , . , , , . , /





?





val itemIdsSet: Set<String> = ...
val currentItemIds: Set<String> = ...
for(itemId in itemIdsSet) {
   if(!currentItemIds.contains(itemId)) {
       repository.exclude(itemId)
   }
}
      
      



:





val itemIdsSet: Set<String> = ...
val currentItemIds: Set<String> = ...
for (itemId in itemIdsSet subtract currentItemIds) {
   repository.exclude(itemId)
}
      
      



API , exclude , :





repository.exclude(itemIdsSet subtract currentItemIds)  
      
      



code style

, “”. : 





  • (, _ enum )









  • companion object ( ) .. 





, . , best practices.





, Kotlin- :





https://developer.android.com/kotlin/style-guide https://proandroiddev.com/an-opinionated-guide-on-how-to-make-your-kotlin-code-fun-to-read-and-joy-to-work-with-caa3a4036f9e 

https://developer.android.com/kotlin/coroutines/coroutines-best-practices








All Articles