美文网首页Kotlin编程
Kotlin基本语法

Kotlin基本语法

作者: 卡路fly | 来源:发表于2020-04-03 15:24 被阅读0次

    javabean

    public class Book {
        private long id;
        private String name;
        
        ...
        getter and setter
        ...
        
    }
    
    data class Book(
        val id: Long,
        val name: String) {
            // 构造函数的函数体可以写在init
            init {
                ...
            }
        }
    }
    data class Forecast(val dtae: Date, val temperature: Float, val details: String)
    

    复制

    val f1 = Forecast(Date(), 22.5f, "Cool")
    val f2 = f1.copy(temperature = 22f)
    

    映射对象到变量

    val f1 = Forecast(Date(), 22.5f, "Cool")
    val (date, temperature, details) = f1
    会被编译为
    val date = f1.component1()
    val temperature = = f1.component2()
    val details = f1.component3()
    

    别名

    import com.animal.dog as puppy  
    

    空安全

    // 不能通过编译,不能为空
    val not NullBook: Book = null
    // 可以为空
    val not book: Book? = null
    // 不能通过编译,book可能为空
    book.print()
    // book != null 执行
    book?.print()
    // 如进行空检查,不需要安全调用操作符调用
    if (book != null) {
        book.print()
    }
    // 确保不为空才会调用,否则抛出异常
    book!!.print()
    // 使用三元运算符来给定一个是Null时的替代值
    val name = book?.name ?: "empty"
    

    习惯用法

    // If not null 缩写
    val files = File("Test").listFiles()
    println(files?.size)
    
    // If not null and else 缩写
    val files = File("Test").listFiles()
    println(files?.size ?: "empty")
    
    // if null 执行一个语句
    val data = ……
    val email = data["email"] ?: throw IllegalStateException("Email is missing!")
    
    // if not null 执行代码
    val data = ……
    data?.let {
        …… // 代码会执行到此处, 假如data不为null
    }
    
    // 使用可空布尔
    val b: Boolean? = ……
    if (b == true) {
        ……
    } else {
        // `b` 是 false 或者 null
    }
    

    Lambdas

    view.setOnClickListener { toast("haha") }
    

    继承

    所有类默认不可继承(final),使用open或abstract声明的类可被继承

    open class Animal(name: String)
    class B(name: String,surname: String) : Animal(name)
    

    函数

    使用fun关键字进行定义。当没有指定返回值时,返回Unit,类似void,但Unit是一个真正的对象。
    当返回结果可用一个表达式计算出来可以使用等号。

    fun add(x: Int,y: Int) : Int = x + y
    

    当函数参数指定为默认值,调用的时候可以不传值进入。

    基本类型

    • 数字/字符类型不会自动转型,必须使用明确的类型转换。
    val i: Int = 7
    val d: Double = i.toDouble()
    val c: Char = 'c'
    val ii: Int = c.toInt()
    
    • 位运算,| 使用 or ,& 使用 and
    val a = flag1 or flag2
    val b = flag1 and flag2
    
    • 字面可以写明具体类型。
    // 没有八进制!!!
    val i = 12
    val iHex = 0x0f
    val l = 3L
    val d = 3.5
    val f  = 3.5F
    
    • String可以像数组一样访问被迭代。
    val s = "aaa"
    val c = s[2]
    for (c in s) {
        pring(c)
    }
    

    val & var

    var: 可变变量

    val: 不可变量。实例化之后不能再去改变状态,如果需要一个对象修改之后的版本,会在再创建一个新的对象。编程更加健壮和可预估,是线程安全的,因为不可变,所有线程访问到的对象都是同一个。尽可能地使用val。

    Companion objects

    使用companion object,里面是静态属性、常量或者函数,就像java中的静态属性或者方法。

    When 表达式

    when 取代了switch

    when (x) {
        1 -> print("x == 1")
        2 -> print("x == 2")
        else -> { // 注意这个块
            print("x is neither 1 nor 2")
        }
    }
    
    // 多个分支条件放在一起,用逗号分隔:
    when (x) {
        0, 1 -> print("x == 0 or x == 1")
        else -> print("otherwise")
    }
    
    // 检测一个值在(in)或者不在(!in)一个区间或者集合中:
    when (x) {
        in 1..10 -> print("x is in the range")
        in validNumbers -> print("x is valid")
        !in 10..20 -> print("x is outside the range")
        else -> print("none of the above")
    }
    
    // 检测一个值是(is)或者不是(!is)一个特定类型的值
    fun hasPrefix(x: Any) = when(x) {
        is String -> x.startsWith("prefix")
        else -> false
    }
    
    // when 取代 if-else if链。
    when {
        x.isOdd() -> print("x is odd")
        x.isEven() -> print("x is even")
        else -> print("x is funny")
    }
    

    操作符表

    一元操作符
    二元操作符 数组操作符 等于操作符

    PS: 操作符 === 和 !== 分别是java中的 == 和 != ,并且不能被重载。


    函数调用

    修饰符

    修饰符 描述
    public 默认修饰符(当类为private,public成员类也不可见)
    private 只能被自己所在文件可见
    protected 只能被用在类或接口中的成员上
    internal 对整个module可见(当类为private,internal修饰的可见性会限制与它所在的这个类的可见性)

    构造器

    构造器默认为public,可以修改为private

    class C private constructor(a: Int) {...}
    

    单例

    class App : Application() {
        companion object {
            var instance: App by DelegatesExt.notNullSingleValue()
        }
        override fun onCreate() {
            super.onCreate()
            instance = this
        }
    }
    

    扩展函数

    toast("free style")
    longToast("free style")
    

    执行一个请求

    public class Request(var url: String) {
        public fun run() {
            val str = URL(url).readText()
        }
    }
    

    主线程外执行

    async() {
        Request(url).run()
        uiThread { longToast("Request performed") }
    }
    

    uiThread 可依赖于调用者,如果被一个activity调用,activity.isFinishing()返回TRUE,uiThread不会执行,所以不会在activity销毁时崩溃~
    异步调用

    async() {
        val res = RequestForecastCommand("1111").execute()
        uiThread {
            forecastList.adapter = ForecastListAdapter(res)
        }
    }
    

    内联函数

    内联函数:编译时被替换,可以减少内存分配格运行时开销。

    (如果一个函数接受一个函数作为它的参数,普通函数内部会创建一个含有那个函数的对象;内联函数会吧我们调用这个函数的地方替换掉,不需要生成一个内部对象。)

    • apply:调用某对象的apply,在函数范围内,可以调用该对象的任意方法并返回该对象,返回当前自己的对象。
    • let:默认当前对象作为闭包的it参数,返回函数内最后一行,或指定return。
    • with:一个单独的函数,返回最后一行,直接调用对象的方法。(let + apply)
    • run:类似apply,返回最后一行。
    // 对一个对象实例调用多个方法 (with)
    // 这个例子才充分体现了with有没有!!!!之前看到的都什么鬼
    class Turtle {
            fun penDown()
            fun penUp()
            fun turn(degrees: Double)
            fun forward(pixels: Double)
    }
    val myTurtle = Turtle()
    with(myTurtle) { // 画一个 100 像素的正方形
            penDown()
            for(i in 1..4) {
                forward(100.0)
                turn(90.0)
            }
            penUp()
    }
    
    函数名 定义 参数 返回值 extension 其他
    let fun <T, R> T.let(f: (T) -> R): R = f(this) it 闭包返回
    apply fun <T> T.apply(f: T.() -> Unit): T { f(); return this } 无(this) this
    with fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f() 无(this) 闭包返回 调用方式不同
    run fun <T, R> T.run(f: T.() -> R): R = f() 无(this) 闭包返回

    区间

    区间表达式由具有操作符形式 .. 的 rangeTo 函数辅以 in 和 !in 形成。

    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) { …… }
    

    相关文章

      网友评论

        本文标题:Kotlin基本语法

        本文链接:https://www.haomeiwen.com/subject/nmnhphtx.html