Android:Kotlin详细入门学习指南-基础语法(一)

Android:Kotlin详细入门学习指南-基础语法(一)

本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新

  • Kotlin被Google官方认为是Android开发的一级编程语言
  • 自 2019 年 Google I/O 以来,Kotlin 就成为了 Android 移动开发的首选。
  • 首先来看看Kotlin的基础语法

Kotlin是什么

  • Kotlin是Android开发的一级编程语言(Google官方认证)
  • 由JetBrains公司在2010年推出 & 开源,与Java语言互通 & 具备多种Java尚不支持的新特性
  • Android Studio3.0后的版本支持Kotlin

优点

  • 码更少、可读性更强 - 花更少的时间来编写代码与理解他人的代码
  • 成熟的语言与环境 - 自 2011 年创建以来,Kotlin 不仅通过语言而且通过强大的工具在整个生态系统中不断发展。 现在,它已无缝集成到 Android Studio 中, 并被许多公司积极用于开发 Android 应用程序。
  • Android Jetpack 与其他库中的 Kotlin 支持 - KTX 扩展 为现有的 Android 库添加了 Kotlin 语言特性,如协程、扩展函数、lambdas 与命名参数。
  • 与 Java 的互操作性 - 可以在应用程序中将 Kotlin 与 Java 编程语言一起使用, 而无需将所有代码迁移到 Kotlin。
  • 支持多平台开发 - 不仅可以使用 Kotlin 开发 Android,还可以开发 iOS、后端与 Web 应用程序。 享受在平台之间共享公共代码的好处。
  • 代码安全 - 更少的代码与更好的可读性导致更少的错误。Kotlin 编译器检测这些剩余的错误,从而使代码安全。
  • 易学易用 - Kotlin 非常易于学习,尤其是对于 Java 开发人员而言。
  • 大社区 - Kotlin 得到了社区的大力支持与许多贡献,该社区在全世界范围内都在增长。 根据 Google 的说法,Play 商店前 1000 个应用中有 60% 以上使用 Kotlin。

使用

1、点击Android Studio settings -> Plugins -> 搜索Kotlin Languages插件
2、在根目录的build.gradle中加入

buildscript {
    ext.kotlin_version = '1.3.61'
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

3、在app/build.gradle中引入

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

buildscript {
    ext.kotlin_version = '1.3.61'
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

基本语法

定义包名 - 在源文件的开头定义包名:包名不必和文件夹路径一致:源文件可以放在任意位置。

package my.demo 
import java.util.
* //...

定义函数:定义一个函数接受两个 int 型参数,返回值为 int

fun sum(a: Int , b: Int) : Int{ 
    return a + b 
}

fun main(args: Array<String>) {
    print("sum of 3 and 5 is ")
    println(sum(3, 5)) 
  }

该函数只有一个表达式函数体以及一个自推导型的返回值:

fun sum(a: Int, b: Int) = a + b 
fun main(args: Array<String>) {
    println("sum of 19 and 23 is ${sum(19, 23)}") 
 }

返回一个没有意义的值:
Unit 的返回类型可以省略

fun printSum(a: Int, b: Int): Unit { 
    println("sum of $a and $b is ${a + b}")
     }
fun main(args: Array<String>) { 
printSum(-1, 8)
     }

定义局部变量
声明常量:

fun main(args: Array<String>) {
     val a: Int = 1 // 立即初始化 
     val b = 2 // 推导出Int型 
     val c: Int // 当没有初始化值时必须声明类型 
     c = 3 // 赋值 
     println("a = $a, b = $b, c = $c")
  }

变量:

fun main(args: Array<String>) {
     var x = 5 // 推导出Int类型 
     x += 1 println("x = $x")
 }

注释:
与 java 和 javaScript 一样,Kotlin 支持单行注释和块注释。

// 单行注释
/* 哈哈哈哈 这是块注释 */

与 java 不同的是 Kotlin 的 块注释可以级联。
使用字符串模板

fun main(args: Array<String>) {
     var a = 1 // 使用变量名作为模板: 
     val s1 = "a is $a" a = 2 // 使用表达式作为模板:
     val s2 = "${s1.replace("is", "was")}, but now is $a" println(s2)
 }

使用条件表达式

fun maxOf(a: Int, b: Int): Int { 
    if (a > b) {
     return a 
     } else { 
     return b
      } 
 }
 fun main(args: Array<String>) { 
    println("max of 0 and 42 is ${maxOf(0, 42)}") 
 }

把if当表达式:

fun maxOf(a: Int, b: Int) = if (a > b) a else b
fun main(args: Array<String>) {
    println("max of 0 and 42 is ${maxOf(0, 42)}")
}

使用可空变量以及空值检查
当空值可能出现时应该明确指出该引用可空。
下面的函数是当 str 中不包含整数时返回空:

fun parseInt(str : String): Int?{ //... }

使用值检查并自动转换
使用 is 操作符检查一个表达式是否是某个类型的实例。如果对不可变的局部变量或 属性进行过了类型检查,就没有必要明确转换:

fun getStringLength(obj: Any): Int? {
 if (obj is String) { 
 // obj 将会在这个分支中自动转换为 String 类型 return obj.length }
 // obj 在种类检查外仍然是 Any 类型 return null
 }

使用循环

fun main(args: Array<String>) {
     val items = listOf("apple", "banana", "kiwi") 
     for (item in items) {
      println(item) 
      }
}

或者这样:

fun main(args: Array<String>) { 
    val items = listOf("apple", "banana", "kiwi") 
    for (index in items.indices) {
     println("item at $index is ${items[index]}") 
     } 
 }

使用 while 循环

fun main(args: Array<String>) { 
     val items = listOf("apple", "banana", "kiwi")
     var index = 0 while (index < items.size) { 
     println("item at $index is ${items[index]}")
      index++
      }
}

使用 when 表达式

fun describe(obj: Any): String = 
    when (obj) {
     1 -> "One" 
     "Hello" ->"Greeting" 
      is Long -> "Long" 
      !is String -> "Not a string" 
      else -> "Unknown" 
  }
  fun main(args: Array<String>) {
         println(describe(1)) println(describe("Hello"))
         println(describe(1000L))
         println(describe(2)) 
         println(describe("other"))
 }

使用ranges
使用 in 操作符检查数值是否在某个范围内:

fun main(args: Array<String>) { 
    val x = 10 
    val y = 9
     if (x in 1..y+1) {
      println("fits in range") 
      } 
 }

检查数值是否在范围外:

if (-1 !in 0..list.lastIndex) { 
    println("-1 is out of range") 
}

使用步进

for (x in 1..10 step 2)
for (x in 9 downTo 0 step 3)

使用集合

对一个集合进行迭代

fun main(args: Array<String>) { 
    val items = listOf("apple", "banana", "kiwi") 
    for (item in items) {
     println(item) 
     } 
 }

使用 in 操作符检查集合中是否包含某个对象

fun main(args: Array<String>) { 
    val items = setOf("apple", "banana", "kiwi") 
    when { 
    "orange" in items -> println("juicy") 
    "apple" in items -> println("apple is fine too") 
    } 
}

使用lambda表达式过滤和映射集合

fun main(args: Array<String>) { 
    val fruits = listOf("banana", "avocado", "apple", "kiwi") 
    fruits 
    .filter { it.startsWith("a") } 
    .sortedBy { it } 
    .map { it.toUpperCase() } 
    .forEach { println(it) 
} 

习惯用语

创建DTOs(POJOs/POCOs) 数据类
相当于java的Bean,

data class Customer(val name: String, val email: String)

给 Customer 类提供如下方法
-为所有属性添加 getters ,如果为 var 类型同时添加 setters -- equals() - - haseCode() -- toString() -- copy()

函数默认值

fun foo(a: Int = 0, b: String = "") {...}

过滤 list

val positives = list.filter { x -> x >0 }

或者更短:

val positives = list.filter { it > 0 }

字符串插值

println("Name $name")

实例检查

when (x) { 
    is Foo -> ... 
    is Bar -> ... 
    else -> ... 
}

遍历 map/list

for ((k, v) in map) {
     print("$k -> $v") 
}

k,v 可以随便命名
使用 ranges

for (i in 1..100) { ... } // 闭区间: 包括100 
for (i in 1 until 100) { ... } // 半开区间: 不包括100 
for (x in 2..10 step 2) { ... } 
for (x in 10 downTo 1) { ... } 
if (x in 1..10) { ... } 
for (i in 1..100) { ... } 
for (i in 2..10) { ... }

只读 list

val list = listOf("a", "b", "c")

只读map

val map = mapOf("a" to 1, "b" to 2, "c" to 3)

访问 map

println(map["key"]) 
map["key"] = value

懒属性(延迟加载)

val p: String by lazy { // 生成string的值 }

扩展函数

fun String.spcaceToCamelCase() { ... } 
"Convert this to camelcase".spcaceToCamelCase()

创建单例模式

object Resource {
    val name = "Name"
}

如果不为空则... 的简写

val files = File("Test").listFiles() 
println(files?.size)

如果不为空...否则... 的简写

val files = File("test").listFiles() 
println(files?.size ?: "empty")

如果声明为空执行某操作

val data = ... 
val email = data["email"] ?: throw IllegalStateException("Email is missing!")

如果不为空执行某操作

val date = ... 
data?.let{ ...//如果不为空执行该语句块 }

返回 when 判断

fun transform(color: String): Int {
     return when(color) { 
     "Red" -> 0 "Green" -> 1 
     "Blue" -> 2 
     else -> throw IllegalArgumentException("Invalid color pa ram value")
      } 
}

try-catch 表达式

fun test() {
     val result = try {
      count() 
      }catch (e: ArithmeticException) {
       throw IllegaStateException(e)
      }//处理 result
}

if 表达式

fun foo(param: Int){ 
    val result = if (param == 1) { 
    "one"
     } else if (param == 2) { 
     "two" 
     } else {
      "three"
       }
}

需要泛型信息的泛型函数的方便形式

// public final class Gson { 
// ... 
// public <T> T fromJson(JsonElement json, Class<T> classOfT ) throws JsonSyntaxException { 
// ... inline 
fun <reified T: Any> Gson.fromJson(json): T = this.fromJs on(json, T::class.java)

命名风格

如有疑惑,默认为Java编码约定,比如:
使用骆

  • 驼命名法(在命名中避免下划线)
  • 类型名称首字母大写
  • 方法和属性首字母小写
  • 缩进用四个空格
  • public 方法要写说明文档,这样它就可以出现在 Kotllin Doc 中

冒号

在冒号区分类型和父类型中要有空格,在实例和类型之间是没有空格的:

interface Foo<out T : Any> : Bar {
    fun foo(a: Int): T
}

Lambdas

在 Lambdas 表达式中,大括号与表达式间要有空格,箭头与参数和函数体间要有 空格。尽可能的把 lambda 放在括号外面传入

list.filter { it > 10 }.map { element -> element * 2 }

在使用简短而非嵌套的lambda中,建议使用 it 而不是显式地声明参数。在使用 参数的嵌套lambda中,参数应该总是显式声明

类声明格式

参数比较少的类可以用一行表示:

class Person(id: Int, name: String)

具有较多的参数的类应该格式化成每个构造函数的参数都位于与缩进的单独行中。 此外,结束括号应该在新行上。如果我们使用继承,那么超类构造函数调用或实现 的接口列表应该位于与括号相同的行中

class Person( 
    id: Int, 
    name: String, 
    surname: String 
    ) : Human(id, name) {
     // ... 
}

对于多个接口,应该首先定位超类构造函数调用,然后每个接口应该位于不同的行 中

class Person( 
    id: Int, 
    name: String, 
    surname: String 
    ) : Human(id, name), 
    KotlinMaker { // ... 
}

构造函数参数可以使用常规缩进或连续缩进(双倍正常缩进)。

Unit

如果函数返回 Unit ,返回类型应该省略:

fun foo() { // ": Unit"被省略了 }

函数 vs 属性

在某些情况下,没有参数的函数可以与只读属性互换。尽管语义是相似的,但是有 一些风格上的约定在什么时候更偏向于另一个。
在下面的情况下,更偏向于属性而不是一个函数:

  • 不需要抛出异常 -- 拥有O(1)复杂度 -- 低消耗的计算(或首次运行结果会被缓 存) -- 返回与调用相同的结果

本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容