Kotlin快速入门指南

本文参考Kotlin中文官网,官网写的很详细,是很好的入门参考资料。这篇文章主要是作为对官方文档的整理,不对原理做过多解释,方便新手快速入门。需要注意的是,你需要有java基础。

一、Kotlin是什么

Kotlin和java一样,是一门编程语言,运行在JVM之上,都需要经过编码——编译——执行的过程,不同的是java代码编译使用的是javac编译器,而kotlin代码使用的是kotlinc编译器。语言没有高低之分,只有使用场景和特性的区别。

二、Kotlin能做什么

kotlin完整包含java特性,所以java能做的kotlin都能做,比如服务器,Android开发。

三、实践

1、创建一个类

class MyClass {
}

这样声明的类默认是final的,无法被继承,要想开放继承,使用open修饰符

open class MyClass {
}

kotlin没有new关键字,创建对象直接使用 类名(参数)的格式

val myClass = MyClass()

1.1、构造函数

java中的构造函数

public class MyClass {
    // 无参构造器,默认。如果显式写出来,则会被带参构造器覆盖
    public MyClass() {
    }
    
    // 带参构造器
    public MyClass(String s) {
    }
}

kotlin中一个类可以有一个主构造函数和一个或者多个次构造函数。如果主构造函数没有任何注解和可见性修饰符,则可省略constructor关键字

// 主构造函数
class MyClass constructor() {
}

// 次构造函数
class MyClass {
    constructor() {
    }
}

// 没有注解和修饰符的著构造函数
class MyClass() {
}

如果有注解或者可见性修饰符,则constructor关键字不能省略,且这些注解和修饰符在它前面

// 有注解和修饰符的主构造函数不能省略constructor关键字
class MyClass private @Inject constructor() {
}

如果类有一个主构造函数,那么次级函数都要直接或间接委托给主构造函数,使用this关键字

// kotlin
class MyClass constructor() {
    constructor(s: String): this() {
    }
}

// 或者
class MyClass() {
    constructor(s: String): this() {
    }
}

如果需要在类中进行初始化,使用init关键字修饰的初始化代码块

class MyClass() {
    init {
        // init job1
    }
    
    init {
        // init job2
    }
    ...
}

初始化代码块是主构造函数的一部分,因此所有初始化代码块都会在主构造函数中优先执行,其次才会执行次构造函数中的代码。

1.2、变量

var:修饰可变量
val:修饰不可变量
成员变量可以和java一样,在类体内声明,注意此时声明变量是必须初始化(或使用lateinit关键字懒初始化)

// 必须初始化
class MyClass {
    lateinit var s1: String
    val s2: String = "S2"
}

也可以在主构造器中声明,此时可以不初始化

// 可以不初始化
class MyClass constructor(
    var s1: String,
    val s2: String = "S2"
) {    
}

// 或者
class MyClass(
    var s1: String,
    val s2: String = "S2"
) {    
}

使用类型推断,可以把类型去掉,变成

var s1 = "S1"

1.3、函数

1.3.1、具名函数

使用fun关键字声明

fun getName(): String {
    return name
}

区别于java,返回类型在函数声明后面,用:隔开,如果没有返回值,用Unit接收,可以省略不写。上面函数还可以简化为单表单表达式函数

fun getName(): String = name
// 或简化为
fun getName() = name

1.3.2、匿名函数

顾名思义就是没有名字的函数,比如下面这种写法

private fun getName() {
    // 变量name接收匿名函数,name表示一个函数,需要两个Int类型入参,返回Int
    val name: (Int, Int) -> Int = { a: Int, b: Int ->
         a+b
    }
    // 调用name函数,传入1,2作为参数,函数结果传递给value
    val value: Int = name(1, 2)
    println(value)
}

// 以上函数调用部分可以直接写成这样
{ a: Int, b: Int ->
    a+b
}(1, 2)

注意,匿名函数如果有返回值,一般不用return,函数体中最后一行的结果默认作为返回值。匿名函数只能出现在其他函数体中,不能独立存在。更多具名函数和匿名函数的介绍,参考这篇文章
Kotlin学习笔记函数篇(1)具名函数和匿名函数

1.3.3、局部函数

kotlin支持局部函数,即一个函数在另一个函数内部

fun getName(s1: String) {
    fun setName(s2: String) {
        println(s1)
    }
}

成员函数可以访问外部函数(闭包)的局部变量。

2、内部类

这部分和java基本相同,在kotlin中普通内部类(也叫嵌套类)默认是static的,不持有外部类引用,

class Outer {
    class Nested {
    }
}

使用inner关键字修饰,那么就不是static的,会持有外部类对象的引用

class Outer {
    private val s: String = "S"
    inner class Nested {
        println(s)
    }
}

匿名内部类

Android中会经常写如下代码

mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // click event
            }
        });

使用kotlin可以这样写

mView.setOnClickListener(object: View.OnClickListener {

            override fun onClick(view: View) {
                // click event
            }
        })

3、集合

3.1、构造集合

可以完全使用Java创建集合的方式,比如

val list = ArrayList<String>()
val map = HashMap<Int, String>()
val set = HashSet<String>()
val sparseArray = SparseArray<String>()

也可以使用kotlin原生库,比如

val list = arrayListOf<String>()
val map = hashMapOf<Int, String>()
val set = hashSetOf<String>()
// SparseArray没有kotlin原生构建方式
val sparseArray = SparseArray<String>()

在构造集合的同时可以初始化,

val list = arrayListOf<String>("1", "2", "3")

3.2、遍历集合

3.2.1、forEach

val list = arrayListOf<String>()
list .forEach { s ->
    println(s)
}

val map = hashMapOf<Int, String>()
map .forEach { entry ->
    println("${entry .key} -> ${entry .value}")
}

3.2.2、for

val list = arrayListOf<String>()
for (s in list) {
    println(s)
}

val map = hashMapOf<Int, String>()
for (entry in map ) {
    println("${entry.key} -> ${entry.value}")
}

3.2.3、iterator

val list = arrayListOf<String>()
val iterator = list .iterator()
while (iterator.hasNext()) {
    println(iterator.next())
}

val map = hashMapOf<Int, String>()
val iterator = map .iterator()
while (iterator.hasNext()) {
    val entry = iterator.next()
    println("${entry.key} -> ${entry.value}")
}

4、条件判断

4.1、if else

用法上kotlin基本和java一致,不同的是,koltin中if else是可以有返回值的,比如

val value = if (条件一) {
    "这是条件一的返回值"
} else {
    "这是else的返回值"
}

if else条件代码块中最后一行代码的结果会默认作为整体的返回值。另外,由于kotlin没有三目运算符,所以可以用if else来提代。

4.2、when

kotlin中的when对应java中的switch case

when (条件) {
    匹配值1 -> {
        println("这是匹配值1的结果")
    }
    匹配值2 -> {
        println("这是匹配值2的结果")
    }
    匹配值3 -> {
        println("这是匹配值3的结果")
    }
    ...
    else -> {
        println("这是没有匹配到的结果")
    }
}

同样,when也可以作为表达式来使用,返回的是条件代码块中最后一行代码的执行结果

val value = when (条件) {
    匹配值1 -> {
        "这是匹配值1的结果"
    }
    匹配值2 -> {
        "这是匹配值2的结果"
    }
    匹配值3 -> {
        "这是匹配值3的结果"
    }
    ...
    else -> {
        "这是没有匹配到的结果"
    }
}

5、空判断

kotlin中默认参数不能为null,在声明一个变量的时候需要初始化,如果定义的变量可以为null,使用?进行标识

val s: String = "S" // 必须初始化,且不能为null
var s1: String? = null // 必须初始化,但可以为null

如果一个变量在声明的时候无法初始化,但又不能为null,此时可以用lateinit来修饰,

lateinit var s3: String // 声明时不必初始化,不可null

注意,lateinit修饰的变量可以不在声明时初始化,但定要在使用前进行初始化,否则会抛异常。

6、作用域函数

作用域函数唯一的作用就是在对象的上下文中执行代码块,也就是说这个作用域指的就是对象的上下文。作用域函数一共5种:letrunwithapply 以及 also。作用域函数的详细介绍参考Kotlin学习笔记_作用域函数

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