Kotlin 基础语法

2019-11-25  本文已影响0人  三天过去了

一、引入

在项目的根目录build.gradle文件中添加kotlin的依赖

buildscript {
    ext.kotlin_version = '1.3.50'
    repositories {
        google()
        jcenter()
        
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

在主module下build.gradle文件中添加kotlin依赖

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

dependencies {
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

二、基本语法

变量&常量

kotlin中没有java中的原始基本类型,在kotlin中使用var修饰变量,val修饰常量;
var 可读可写
val 只读权限

var a: Int = 1
a = 2

由于kotlin可以自动推导出变量的类型,所以我们通常不用指定变量的类型

val a = "hello" // 此处类型为String
val b = 1 // 此处类型为Int

函数的写法

/**
 * 写一个求和函数
 * 参数名在前面,参数类型在后面,返回值类型在函数的末尾
 */
fun sum(a: Int, b: Int): Int {
    return a + b
}

/**
 * Unit表示无返回值,类似Java中的void,Unit也可以省略
 */
fun unitFunction(a: String, b: String): Unit {
    println(a + b)
}

/**
 * 函数可以指定默认值,此处b的默认值为10
 */
fun sum1(a: Int, b: Int == 10): Int {
    // 由于有默认值,所以可以值传一个参数,如sum1(1) = 11
    return a + b
}

字符串模板

字符串模板是一个很方便的功能,可以直接在字符串使用任意表达式

//字符串模板
fun stringTemplate() {
    var a = 1
    val s1 = "a is $a"

    a = 2
    //在模板中可以使用任意表达式
    val s2 = "${s1.replace("is", "was")}, but now is $a"
    println(s2)
}

条件表达式

条件表示和Java类似

fun maxOf(a: Int, b: Int): Int {
    if (a > b) {
        return a
    } else {
        return b
    }
}

空值和null检测

在kotlin中,默认定义的变量是不能为null的,这可以避免很多NullPointException;
指定一个变量可null是通过在类型的后面加一个问号

// 如果此处没有?,则会编译报错
var a: String? = "aaa"
a = null
// 由于此处a可空,所以编译器认为不能直接使用.length方法,所以直接报错
val length = a.length
// 如果你觉得这个变量一定不为空,也可以添加!!来让编译器忽略空检测,当然这样很不安全,如果是null,则会直接抛异常
val length1 = a!!.length

函数返回值可空

fun checkNull(str: String): Int? {
    if (str == "a") {
        return 1
    } else {
        return null
    }
}

fun checkNullTest(arg1: String, arg2: String) {
    val a1 = checkNull(arg1)
    val a2 = checkNull(arg2)

    // 由于此处a1和a2均可空,所以无法直接调用,需要加一层判断
    if (a1 != null && a2 != null) {
        val sum = a1 * a2
    } else {
        //a1 or a2 is null
    }
}

类型检测与自动类型转换

类似Java中的instanceof关键字

fun typeOfTest(arg1: Any): Int? {
    if (arg1 is String) {
        // 此处arg1已经转换成String,所以可以直接调用.length方法
        return arg1.length
    }
    //此处还是Any类型
    return null
}

for循环

fun loopTest() {
    val items = listOf(1, "aaaa", "sss", 2)

    // 方式1 类似java中的foreach
    for (item in items) {
        println(item)
    }

    // 方式2 迭代出items的index
    for (index in items.indices) {
        println("index is $index value is ${items[index]}")
    }
}

while循环

fun whileTest() {
    val items = listOf<String>("a", "b", "c", "d")

    var index = 0
    while (index < items.size) {
        println("while loop: value is ${items[index]}")
        index++
    }
}

when表达式

when表达式和java中的switch类似,但是功能更强大一些,支持任意类型

fun whenTest(x: Any) {
    when (x) {
        1 -> println("x = 1")
        2 -> println("x = 2")
        "hello" -> println("x = hello")
        else -> {
            println("x = other")
        }
    }
}

由于when为一个表达式,所以也可以返回一个值

val result = when(x) {
    1 -> "x = 1"
    else -> "other"
}

接口定义

接口定义和Java类似,它们都可以包含抽象方法,使用关键interface修饰

interface CommonCallback {

    companion object {
        // 定义静态的属性、常量
        val TYPE_FINANCE_CARD = "finance_card"

        val TYPE_FINANCE_PRODUCT = "finance_product"
    }

    fun onCallback()

    fun onCheckedChange(checked: Boolean)
}

扩展函数

扩展函数是指在一个类上增加一种新的行为,在Java中,通常会实现很多带有static方法的工具类。kotlin中的扩展函数的一个优势就是我们不需要在调用方法的时候把整个对象当做参传递,扩展函数表现的就像是属于这个类一样,而且我们可以使用this关键字、所有的public方法。

/**
 * 给Context创建一个扩展函数customToast,这个函数不需要传入任何context,它可以被任何Context或者它的子类调用
 * 比如Activity或者Service
 */
fun Context.customToast(msg: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(this, msg, duration).show()
}

在Activity中调用

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        customToast("short customToast")
        customToast("long customToast", Toast.LENGTH_LONG)
    }
}

类定义

User类构造函数,init为函数体,此处可以直接使用类头的参数

class User(name: String, age: Int) {

    var mName = ""
    var mAge = ""

    init {
        // 构造函数的函数体
        this.mName = name
        this.mAge = name
    }

    fun test() {
        println("my name is $mName, i'm $mAge years old")
    }
}

还有一种简单的写法,就像普通的属性,在主构造函数中的属性可以是var或者val

class User1(val name: String, val age: Int) {

    fun test() {
        println("my name is $name, i'm $age years old")
    }
}

三、Android Studio

在Android Studio中提供了一些小工具帮助我们更好的学习Kotlin

将Java文件转换成Kotlin文件

image

转换后

image

查看Kotlin对应的Java代码

Tools --> Kotlin --> Show Kotlin ByteCode,然后点击Decompile

Kotlin代码

image

反编译后的Java代码

image
上一篇下一篇

猜你喜欢

热点阅读