Guia de estilo do Kotlin para desenvolvedores Android (Parte I)

Este artigo cobre não apenas as questões estéticas de formatação, mas outros tipos de convenções e padrões que os desenvolvedores Android precisam saber.





O foco principal é, antes de tudo, as regras rígidas seguidas pelos desenvolvedores do Google em todos os lugares!





A princípio pensei que o artigo seria pequeno, mas devido ao enorme número de exemplos de código, ele cresceu bastante.





Então decidi dividi-lo em duas partes.





Ambas as partes contêm uma descrição dos padrões de código na linguagem de programação Kotlin.





:





  • , , , ..









  • - , , , , .









().





!





, .





UTF-8 .





, , : + .kt





( enum



) , :





// PhotoAdapter.kt

class PhotoAdapter(): RecyclerView.Adapter<PhotoViewHolder>() {
	// ...
}


// Utils.kt

class Utils {}

fun Utils.generateNumbers(start: Int, end: Int, step: Int) {
	// ...
}

// Map.kt

fun <T, O> Set<T>.map(func: (T) -> O): List<O> = // ...
fun <T, O> List<T>.map(func: (T) -> O): List<O> = // ...
      
      



Kotlin .kt :





  • , ()





  • ,





  • package





  • import





  • (, , )





:





/*
 * Copyright 2021 MyCompany, Inc.
 *
 *
 */
      
      



KDoc :





/** 
 * Copyright 2021 MyCompany, Inc.
 *
 */

// Copyright 2021 MyCompany, Inc.
//
      
      



@file



, use-site target package



:





/*
 * Copyright 2021 MyCompany, Inc.
 *
 */

@file:JvmName("Foo")

package com.example.android
      
      



package



import



:





package com.example.android.fragments  //  

import android.view.LayoutInflater //    
import android.view.View
      
      







import



, .





:





 import androidx.room.*  //    
      
      



Kotlin , , typealias



.





. extension , .









, .





, .





: , ,





, .





ASCII (0x20).





, :









  • Tab





, (\b, \r, \t, \\



) , Unicode (: \u000a



).





, ASCII, Unicode (∞), Unicode (\u221e



).





, :





//  :   
val symbol0 = "∞"	

// :       Unicode 
val symbol1 = "\u221e" // ∞	

// :    ,     
val symbol2 = "\u221e"

// :  Unicode    
return "\ufeff" + content	//    

      
      



!





when



if



( if



else



):





if (str.isEmpty()) return

when (option) {
    0 -> return
    // …
}
      
      



if, for, when



do



while



:





if (str.isEmpty())
    return  //   !

if (str.isEmpty()) {
    return  // OK
}
      
      



:









  • c









  • , , , .





class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        // ...
    }
}
      
      



K&R:





try {
    val response = fetchDogs("https://api.dog.com/dogs")
} catch (e: Exception) {} // 

try {
    val response = fetchDogs("https://api.dog.com/dogs")
} catch (e: Exception) {
} // OK
      
      



if/else



, :





val value = if (str.isEmpty()) 0 else 1  // OK

val value = if (str.isEmpty())	// 
	0
else
	1

val value = if (str.isEmpty()) { 	// OK
	0
} else {
	1
}

      
      



4 . ( ).





(;



)





100 .





:





  • , (: URL)





  • package



    import







  • , shell





:





  • infix .





  • , :





    • (.



      , .?



      )





    • (::



      )









  • (,)







  • (->



    ) lambda





, ( 4 ):





fun makeSomething(
  val param1: String,
  val param2: String,
  val param3: Int
) {

}
      
      



:





override fun toString(): String {
	return "Hello, $name"
}

override fun toString() = "Hello, $name"
      
      



, - - :





fun waitMe() = runBlocking {
	delay(1000)
}
      
      



(=



):





 val binding: ListItemBinding = 
 	DataBindingUtil.inflate(inflater, R.layout.list_item, parent, false)
      
      



get



set



(4 ):





 val items: LiveData<List<Item>>
 	get() = _items
      
      



Read-only :





val javaExtension: String get() = "java"

      
      



:





  • : , ,





    • . ( backing )









  • ()





( ) ASCII :





  • , : if



    , for



    catch



    :





// 
for(i in 1..6) {
}

// OK
for (i in 1..6) {
}
      
      



  • , else



    catch



    :





// 
}else {
}

// OK
} else {
}
      
      



  • :





// 
if (items.isEmpty()){
}

// OK
if (items.isEmpty()) {
}
      
      



  • :





// 
val four = 2+2

// OK
val four = 2 + 2

//        (->)

// 
items.map { item->item % 2 == 0 }

// OK
items.map { item -> item % 2 == 0 }
      
      



  • : (::



    ), (.



    ) range (..



    )





// 
val str = Any :: toString

// OK
val str = Any::toString

// 
item . toString()

// OK
item.toString()

// 
for (i in 1 .. 6) {
		println(i)
}

// OK
for (i in 1..6) {
		println(i)
}
      
      



  • Antes de dois pontos ( :



    ) para indicar uma extensão de uma classe base ou interface, e em uma when



    expressão para tipos genéricos:





// 
class Worker: Runnable

// OK
class Worker : Runnable

// 
fun <T> min(a: T, b: T) where T: Comparable<T>
  
// OK
fun <T> min(a: T, b: T) where T : Comparable<T>
      
      



  • Depois de dois pontos ( :



    ) ou vírgula ( ,



    )





// 
val items = listOf(1,2)

// OK
val items = listOf(1, 2)

// 
class Worker :Runnable

// OK
class Worker : Runnable
      
      



  • Em ambos os lados da barra dupla:





// 
var debugging = false//  

// OK
val debugging = false //   
      
      



Conclusão

Este artigo acabou por ser bastante longo, espero que você o leia com utilidade.





No próximo artigo: nomenclatura, construções especiais e documentação.





Links Úteis:





  • Guia de estilo Kotlin (em inglês)





  • Estilo K&R





  • Livro: Código Limpo (Bob Martin)





  • Resumidamente sobre o livro de Bob Martin





Aguarde a próxima parte!












All Articles