一速址、 命名格式
總體來說,Kotlin命名格式要和Java命名規(guī)范保持一致荠呐,因?yàn)镵otlin也是JVM兼容的語言竖独。
包名
包的命名規(guī)則和Java一樣:全小寫裤唠,當(dāng)遇到多個詞連接的場景,不要使用下劃線(_)和連字號(-)莹痢。
推薦
package vn.asiantech.android
不推薦
package Vn.Asiantech.Android
類和接口
命名遵守大駝峰規(guī)則(首字母大寫)种蘸。
推薦
HomeActivity
MainFragment
方法
命名遵守小駝峰規(guī)則(首字母小寫)墓赴。
推薦
setData
getApiNews
字段(Fields)
總體來說,字段命名遵守小駝峰規(guī)則劈彪,不建議使用匈牙利法竣蹦。
推薦
class MyClass {
var publicField: Int = 0
val person = Person()
private var privateField: Int?
}
而伴生對象中的常量定義要遵守規(guī)則:全大寫顶猜,單詞連接使用下劃線沧奴。
companion object {
const val THE_ANSWER = 42
}
二、變量和參數(shù)
一句話概括: 小駝峰命名法长窄。
不建議使用單個字符的變量滔吠,除非是循環(huán)中的臨時變量。
其他
首字母縮略詞作為完整單詞看待挠日,適時選擇命名規(guī)則疮绷。
推薦
XMLHTTPRequest
URL: String?
findPostByID
不推薦
XmlHttpRequest
url: String
findPostById
三、間距
縮進(jìn)
縮進(jìn)使用4個空格嚣潜,不建議使用tabs - 制表符冬骚。
閉包
閉包的縮進(jìn)使用2個空格,
推薦
for (i in 0..9) {
Log.i(TAG, "index=" + i)
}
不推薦
for (i in 0..9) {
Log.i(TAG, "index=" + i);
}
自動換行
新的換行縮進(jìn)使用4個空格懂算,而不是默認(rèn)的8個只冻。
推薦
val widget: CoolUiWidget =
someIncrediblyLongExpression(that, reallyWouldNotFit, on, aSingle, line)
不推薦
val widget: CoolUiWidget =
someIncrediblyLongExpression(that, reallyWouldNotFit, on, aSingle, line)
換行
- 每行不應(yīng)超過130個字符,這在Android Studio內(nèi)可以配置计技。
- 如果單行代碼超過限制需要換行顯示喜德,使用, / : / { , = 作為首行的結(jié)尾。
推薦
fun setData(name: String, age: Int, class: String, date: String, message: String,
time: String) {
}
fun getInfo(name: String, birth: String, age: Int, weight: Float, hight: Float) =
getInfo().apply {
}
data class Animal(private val weight: Float, private val hight: Float) :
AbstractAnimal() {
}
垂直間距
方法體之間保留一個空行垮媒,這樣可以讓結(jié)構(gòu)清晰舍悯。
方法體內(nèi)的空行用來分割不同功能,這樣如果一個方法內(nèi)分多個部分睡雇,也許需要重構(gòu)代碼了萌衬。
冒號 (:)
- 類型和父類型之間的冒號前面要保留空格,而變量和類型之間的冒號前沒有空格它抱。
推薦
interface Foo<out T : Any> : Bar {
fun foo(a: Int): T
}
// 申明變量類型
val firstName: String
不推薦
interface Foo<out T:Any>: Bar {
fun foo(a : Int):T
}
// 申明變量類型
val firstName:String
- 在定義類的時候奄薇,在結(jié)構(gòu)體的右括號和類主題的左括號之間保留空格,結(jié)構(gòu)體的每個參數(shù)單行顯示抗愁。
推薦
class User(
public open var firstName: String,
public open var lastName: String
) {}
不推薦
class User(public open var firstName: String, public open var lastName: String){}
- 在定義子類或?qū)崿F(xiàn)接口的時候馁蒂,上面提到的規(guī)則仍然適用,且冒號和父類名之間要保留空格蜘腌,冒號和結(jié)構(gòu)體之間不需要空格沫屡。
推薦
class User(
public open var firstName: String,
public open var lastName: String
): RealmObject() {}
分號(;)
在Kotlin中避免使用分號。
推薦
val horseGiftedByTrojans = true
if (horseGiftedByTrojans) {
bringHorseIntoWalledCity()
}
不推薦
val horseGiftedByTrojans = true;
if (horseGiftedByTrojans) {
bringHorseIntoWalledCity();
}
括號格式 {}
- 方法體的大括號和其他大括號首括號和前面代碼在同一行撮珠,尾括號新起一行沮脖。
推薦
class MyClass {
fun doSomething() {
if (someTest) {
// ...
} else {
// ...
}
}
}
不推薦
class MyClass
{
fun doSomething()
{
if (someTest)
{
// ...
}
else
{
// ...
}
}
}
if 條件 括號格式
- 條件判斷語句必須內(nèi)嵌在括號里金矛,無論其是多少行。
推薦
if (someTest) {
doSomething()
}
if (someTest) { doSomethingElse() }
不推薦
if (someTest)
doSomething()
if (someTest) doSomethingElse()
四勺届、類型
盡可能使用Kotlin原生類型驶俊。
Unit
避免顯式地聲明Unit類型,因?yàn)椴伙@式聲明返回類型的函數(shù)都會返回 Unit 類型免姿。
推薦
fun doSomething()
不推薦
fun doSomething(): Unit
類型推導(dǎo)
優(yōu)先使用類型推導(dǎo)
推薦
val something = MyType()
val meaningOfLife = 42
不推薦
val something: MyType = MyType()
val meaningOfLife: Int = 42
常量 vs 變量
定義常量時使用關(guān)鍵詞val饼酿, 定義變量時使用關(guān)鍵詞var。
建議: 把所有的值使用val定義胚膊,且只在編譯器警告的時候修訂為var故俐。
伴生對象
伴生對象應(yīng)定義在類文件的上面,而關(guān)于伴生對象的命名規(guī)范要遵守Java標(biāo)準(zhǔn)規(guī)范紊婉。表示常量 需加 const
推薦
class MainFragment: Fragment() {
companion object {
const val TYPE_VIEW_HEADER = 0
const val TYPE_VIEW_FOOTER = 1
}
}
不推薦
class MainFragment: Fragment() {
companion object {
val TypeViewHeader = 0
val TypeViewFooter = 1
}
}
字符串
推薦使用字符串插值語法糖 ${}
推薦
val fullName = "${user.firstName} ${user.lastName}"
不推薦
val fullName = user.firstName + " " + user.lastName
選配型(?)
變量和方法返回可以聲明為選配型药版,這種情況賦值null也是允許的。
使用隱式拆包!!時候要小心喻犁,只能在確認(rèn)實(shí)例對象在被使用前已經(jīng)初始化槽片,如在Activity方法onCreate使用的子視圖。
在為選配型變量和參數(shù)命名的時候肢础,不用使用類maybeView 和 optionalString的名稱还栓,因?yàn)檫x配類型已經(jīng)表明了這一點(diǎn)。
在訪問選配型變量值時乔妈,可使用可選鏈(Optional Chaining)蝙云。
editText?.setText("foo")
五、習(xí)慣
使用IDE提示
val array = ArrayList<Int>()
array[0]
// or
activity().finish()
不推薦
val array = ArrayList<Int>()
array.get(0)
// or
getActivity().finish()
it 在 Lambda 語句中適應(yīng)較廣范圍路召。
推薦
{
it?.let { animal -> animal.foo() }
}
不推薦
{ animal ->
animal?.let { it.foo() }
}
使用類型推斷勃刨,除非是難以理解的時候。
推薦
//屬性
val age = 0 // Int
val foo = 10L // Long
val height = 100f // Float
//函數(shù)
// return Boolean
fun Context.isConnectToWifi() =
(getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager)
.activeNetworkInfo?.type == ConnectivityManager.TYPE_WIFI
// return Point
fun Display.getSize(): Point = Point().apply { getSize(this) }
不要顯式地寫for循環(huán)股淡。
Kotlin中集合的支持forEach遍歷身隐。
推薦
(0..9).forEach {
// todo somethings
}
(0..9).forEachIndexed { index, value ->
// todo somethings
}
不推薦
for (i in 0..9) {
// todo somethings
}
使用 to 快速創(chuàng)建Pair類的實(shí)例。
推薦
val pair = Pair(foo, bar)
不推薦
val pair = foo to bar
使用優(yōu)雅的類型轉(zhuǎn)換唯灵。
推薦
dog as? Animal ?: throw IllegalArgumentException("not Animal!")
dog.foo()
不推薦
if (dog !is Animal) {
throw IllegalArgumentException("not Animal!")
}
dog.foo()
Getters & Setters
Kotlin中推薦直接訪問屬性贾铝。
推薦
// syntax
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
// 自定義setter
var stringRepresentation: String
get() = this.toString()
set(value) {
setDataFromString(value) // parses the string and assigns values to other properties
}
在自定義Getters & Setters時,要遵守Kotlin官方規(guī)范埠帕。
When語句
Kotlin的When語句和Java中的Switch有稍許區(qū)別垢揩,如不會fall through。如果不同的case具有相同的處理策略敛瓷,使用逗號(,),并且else語句是必須的叁巨。
推薦
when (anInput) {
1, 2 -> doSomethingForCaseOneOrTwo()
3 -> doSomethingForCaseThree()
else -> println("No case satisfied")
}
不推薦
when (anInput) {
1 -> doSomethingForCaseOne()
2 -> doSomethingForCaseOneOrTwo()
3 -> doSomethingForCaseThree()
}
變量可視性修飾符
默認(rèn)修飾符是public,如果沒有其他需要可以省略呐籽。
推薦
val wideOpenProperty = 1
private val myOwnPrivateProperty = "private"
不推薦
public val wideOpenProperty = 1
private val myOwnPrivateProperty = "private"
訪問控制修飾符
對于每個類锋勺,方法和成員變量蚀瘸,訪問控制修飾符要顯示定義清晰。
變量和字段
單行一個聲明庶橱。
推薦
username: String
twitterHandle: String
類
普遍來說贮勃,每一個文件定義一個類,對于適合的場合依然可以使用內(nèi)部類苏章。
Data 類型對象
對于簡單的數(shù)據(jù)結(jié)構(gòu)寂嘉,推薦使用data類。
推薦
data class Person(val name: String)
不推薦
class Person(val name: String) {
override fun toString() : String {
return "Person(name=$name)"
}
}
枚舉
優(yōu)先使用靜態(tài)變量布近,避免使用枚舉類垫释,因?yàn)?a target="_blank">內(nèi)存開銷太大丝格。
如果枚舉類沒有其他方法撑瞧,不用換行。
推薦
private enum CompassDirection { EAST, NORTH, WEST, SOUTH }
六显蝌、注解(Annotations)
使用Java式標(biāo)準(zhǔn)注解预伺,特別是override, 關(guān)鍵字要和函數(shù)的聲明保持同一行曼尊。
推薦
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
}
不推薦
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
}
Annotations應(yīng)該在類的上面酬诀, 內(nèi)聯(lián)如果注解類中的字段,
推薦
@Root(strict=false)
public open class User (
@field:Element public open var firstName: String? = "",
@field:Element public open var lastName: String? = "",
) {...}
不推薦
@Root(strict=false) public open class User (
@field:Element
public open var firstName: String? = "",
@field:Element
public open var lastName: String? = "",
) {...}
七、XML
XML文件命名
文件名要以展示視圖的類型作為前綴骆撇。
推薦
activity_login.xml
fragment_main_screen.xml
button_rounded_edges.xml
不推薦
login.xml
main_screen.xml
rounded_edges_button.xml
縮進(jìn)
和Java一樣瞒御, XML文件使用2個字符縮進(jìn)。
使用上下文相關(guān)的XML
任何時候神郊,XML都要定義在相關(guān)的文件內(nèi)肴裙。
Strings => res/values/strings.xml
Styles => res/values/styles.xml
Colors => res/color/colors.xml
Animations => res/anim/
Drawable => res/drawable