美文网首页
Kotlin 基础

Kotlin 基础

作者: PaulLuv | 来源:发表于2018-03-21 10:54 被阅读12次
  1. 基础类型
    Double Float Long Int Short Byte,类型间的转换都有提供方法 如.toInt()等。

  2. Class类
    Kotlin中所有的类都是final,如果允许别的类继承这个类,需要添加open注解。
    主构造函数不能包含任意代码。初始化代码可以放在init做前缀的初始化块内

class Customer(name: String) {
    init {
        logger,info("Customer initialized with value ${name}")
    }
}
  1. 密封类
    密封类用于代表严格的类结构,值只能是有限集合中的某种类型。这就相当于一个枚举类的扩展:枚举值集合的类型是严格限制的,但是每个枚举常量只有一个实例,而密封类的子类可以有包含不同状态的多个实例。
    实例如下:
/**
 * 心跳包.. Result
 */
sealed class HeartBeatReqResult{
    class Error(val error:Exception):HeartBeatReqResult()
    class Ack(val ack:AutoId):HeartBeatReqResult()
}

密封类的子类的扩展可以在任何地方,不必在密封类声明内部进行。

  1. 类的属性与字段
    完整属性声明语法:
var <propertyName>: <PropertyType> [ = <property_initializer> ]
    <getter>
    <setter>
  1. 延迟初始化lateinit
    lateinit只能用在类的var类型的可变属性中,不能用在构造方法中,并且属性不能有getter和setter访问器。这个属性的类型必须是非空的,同样也不能是基本类型。

  2. 可见行修饰
    internal同一模块内可见。

  3. 函数扩展

fun <T> MutableList<T>.swap(x: Int, y: Int) {
  val tmp = this[x] // 'this' corresponds to the list
  this[x] = this[y]
  this[y] = tmp
}
  1. 扩展是被静态解析的
    扩展实际上并没有修改它所扩展的类。定义一个扩展,你并没有插入一个新的成员,只是能够让类的实例对象能够通过.调用新的函数。
  • 如果有同名同参数的成员函数和扩展函数,调用的时候必然会使用成员函数。
class C {
    fun foo() { println("member") }
}
fun C.foo() { println("extension") }
调用``c.foo()``的时候,他会输出"member",而不是"extension"
  • 扩展函数是静态分发的,扩展函数的调用是由发起函数调用的表达式决定的,而不是在运行时动态获取的表达式决定的。
open class C
class D: C()
fun C.foo() = 'c'
fun D.foo() = 'd'
调用``c.foo()``的时候,输出"c",  
调用``d.foo()``的时候,输出"d".
  1. 数据类data class
    编译器会自动根据主构造函数中声明的所有属性添加equal()/hashCode/toString()/copy()函数
    copy属性
val jack = User(name = "jack", age = 1)
val olderJack = jack.copy(age = 2)

标准数据类提供了PairTriple

  1. 内部类
    类可以嵌套在其他类中,类可以标记为inner这样就可以访问外部类的成员。内部类拥有外部类的一个对象引用:
class Outer {
    private val bar: Int = 1
    inner class Inner {
        fun foo() = bar
    }
}
val demo = Outer().Inner().foo() //==1

11.匿名内部类
匿名内部类的实例是通过对象表达式创建的:

window.addMouseListener(object: MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }
    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})
  1. 对象表达式
    有时候我们只需要一个没有父类的对象,可以这样写
val adHoc = object {
    var x: Int = 0
    var y: Int = 0
}
print(adHoc.x + adHoc.y)

13.对象声明

  • 单例声明
object Singleton
  • 伴随对象
class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}
val instance = MyClass.create()

14.代理属性

val/var <property name>: <Type> by <expression>
  • 代理延迟
    lazy()是一个接受 lamdba 并返回一个实现延迟属性的代理:第一次调用 get() 执行 lamdba 并传递 lazy()并存储结果,以后每次调用get()时只是简单返回之前存储的值。
val lazyValue: String by lazy {
    println("computed!")
    "Hello"
}

fun main(args: Array<String>) {
    println(lazyValue)
    println(lazyValue)
}
//// 输出
computed!
Hello
Hello
  • 可观察属性
    Delegates.observable()需要两个参数:一个初始值和一个用于修改的 handler 。每次我们给属性赋值时都会调用handler (在初始赋值操作后)。它有三个参数:一个将被赋值的属性,旧值,新值:
import kotlin.properties.Delegates

class User {
    var name: String by Delegates.observable("<no name>") {
        prop, old, new ->
        println("$old -> $new")
    }
}

fun main(args: Array<String>) {
    val user = User()
    user.name = "first"
    user.name = "second"
}
//// 输出
\ -> first
first -> second
  • 在Map中存储属性
    把属性值存储在 map 中是一种常见的使用方式,这种操作经常出现在解析 JSON 或者其它动态的操作中。这种情况下你可以使用 map 来代理它的属性。
class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int     by map
}
class MutableUser(val map: MutableMap<String, Any?>) {
    var name: String by map
    var age: Int     by map
}
  1. 尾递归函数
    Kotlin 支持函数式编程的尾递归。这个允许一些算法可以通过循环而不是递归解决问题,从而避免了栈溢出。当函数被标记为 tailrec 时,编译器会优化递归,并用高效迅速的循环代替它。

使用 tailrec 修饰符必须在最后一个操作中调用自己。在递归调用代码后面是不允许有其它代码的,并且也不可以在 try/catch/finall 块中进行使用。当前的尾递归只在 JVM 的后端中可以用

tailrec fun findFixPoint(x: Double = 1.0): Double 
    = if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))

等价于
private fun findFixPoint(): Double {
    var x = 1.0
    while (true) {
        val y = Math.cos(x)
        if ( x == y ) return y
        x = y
    }
}

16.协程
一般来说,协程是一种可以不阻塞线程但却可以被挂起的计算过程。线程阻塞总是昂贵的,但协程的挂起基本没有什么开销。

  • 挂起函数 suspend
suspend fun doSomething(foo: Foo): Bar{
 ... 
}
  1. Ranges
.. step
downTo step
in 
!in
  1. 类型检查与转换
is
!is
as
as?
  1. 空安全
?.
?:
.let{ }
as?
!!
  1. 函数引用
fun isOdd(x: Int) =x % 2 !=0
val numbers = listOf(1, 2, 3)
println(numbers.filter( ::isOdd) ) //prints [1, 3]
  1. 属性引用
    在 kotlin 中访问顶级类的属性,我们也可以使用 :: 操作符:
var x = 1
fun main(args: Array<String>) {
    println(::x.get())
    ::x.set(2)
    println(x)
}

相关文章

网友评论

      本文标题:Kotlin 基础

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