美文网首页Kotlin学习
Kotlin Basic Learning - series 3

Kotlin Basic Learning - series 3

作者: swust_cp | 来源:发表于2018-04-17 19:42 被阅读8次
  1. Kotlin可以使用lazy来推迟一些开销比较大的初始化,直到真正需要的时候(第一次调用get的时候)才进行初始化,后续继续调用get,则不再执行传入的lambda

    val lazyValue: String by lazy {
       println("computed!") 
        "hello"
    }
    fun main(args: Array<String>) {
        println(lazyValue)
        println(lazyValue)
    }
    // example output:
    
    // computed!
    // hello
    // hello
    

    简单总结:对于在对ready-only的property(i.e. a val), 它的delegate(by后面的类型)需要提供一个叫getValue的函数,并且两个参数,返回必须是property的类型(String)或者它的子类

    • thisRef:必须是property owner或者property owner的supertype(一般是当前property所属的class)
    • property:必须是KProperty<*>或者它的supertype(比如lazyValue:String)

    对于mutable的propert(a var),它的delegate还需要提供一个setValue,参数除了上面两个,最后一个是new value,必须和property的类型相同或者它的子类

    lazy更像一个Single Instance of Variable,是不是和单例有点类似

    Delegated Properties - Kotlin Programming Languagekotlinlang.org

  2. 在Kotlin中non-null的变量必须要马上进行初始化,如果你的程序是稍后(在适当的时候)才给它初始化,就可以通过添加lateinit表示initialize me later!它最终还是null safe的,另外lateinit不能用在primitive type上面。比如在Android开发时,我们的View一般都是在onCreate中进行初始化,或者Dagger2在注入时

    @Inject
    lateinit var myUtil: MyUtil
    

    lazylateinit使用场景,它们的使用目的不一样,有时还是要具体场景具体分析:

    • 如果是mutable的,使用lateInit
    • 如果是只需要初始化一次,其他地方都可以使用
    class MyActivity: AppCompatActivity() {
        lateinit var recyclerView: RecyclerView // non-null, but not initialized
        
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            
            // ..
            recyclerView = findViewById(R.id.recycler_view) // initialize here
        }
    }
    

    Properties and Fields: Getters, Setters, const, lateinit - Kotlin Programming Languagekotlinlang.org

  3. 你的函数参数是否有效呢?可以在用之前通过'require'进行检测,如果invalid,则会抛出IllegalArgumentException

    fun setName(name: String) {
         // calling setName("") throws IllegalArgumentException
            require(name.isNotEmpty()) { "invalid name" }
         //..
        }
    

    require - Kotlin Programming Languagekotlinlang.org

  4. Inline function,通过在函数前面添加inline修饰符,表明他被调用的时候,在调用它的地方,不仅仅是inline函数自己本身,包括它的lambda参数,都会被替换/inline。inline使用场景:比如设置某些高频率调用的方法或者方法比较大的时候,可以减少运行时的进栈出栈和保存状态的开销。比如:消除了因为保存lambda表达式函数对象而造成的内存损耗。

    // define an inline function that takes a function argument
    inline fun onlyIf(check: Boolean, operation: () -> Unit) {
        if (check) {
            operation()
        }
    }
    
    // call it like this
    onlyIf(shouldPrint) {
        println("Hello, Kt")
    }
    
    //which will be inline to this
    if (shouldPrint) {   // execution: no need to create lambda
        println("Hello, kt")
    }
    

    在Kotlin中我们可以使用return来退出一个named function或者anonymous function,但在退出一个lambda时,我们使用label, return是禁止使用的,因为一个lambda can not make the enclosing function return。如果是inline function则可以使用return,表示退出整个函数。

    在Kotlin中普通的return同在Java中一样,相对应的都是方法返回字节码,而方法返回字节码的字面意就是退出处于当前栈顶的执行方法,Inline Function的lambda函数执行其实都在enclosing函数的闭包中,return退出lambda其实也就是退出enclosing函数。lambda不能直接退出没被 inline 修饰的函数是因为lambda函数的执行都是在其 Function对象的invoke() 中,即使能return也仅仅是退出invoke()而也。

    fun foo() {
        ordinaryFunction {
            return // ERROR: can not make `foo` return here
        }
    }
    
    // 如果是inline funciton
    fun foo() {
        inlineFunction {
            return // OK: the lambda is inlined
        }
    }
    
    fun hasZeros(ints: List<Int>): Boolean {
        ints.forEach { // forEach是inline的
            if (it == 0) return true // returns from hasZeros
        }
        return false
    }
    

    Inline Functions and Reified Type Parameters - Kotlin Programming Languagekotlinlang.org

  5. 在同一project中使用Kotlin和Java,怎样进行调用呢?在编译时默认会将kotlin文件的类名变成“YourFileKt”。可以通过@file:JvmName("xxx")来重新进行命名

    // Default
    // File: ShapesGenerator.kt
    package com.shapes
    
    fun generateSquare() = Square()
    fun generateTriangle() = Triangle()
    
    // Java usage:
    ShapesGeneratorKt.generateSquare()
    
    
    // Custom
    // File: ShapesGenerator.kt
    @file:JvmName("ShapesGenerator")
    package com.shapes
    
    fun generateSquare() = Square()
    fun generateTriangle() = Triangle()
    
    // Java usage
    ShapesGenerator.generateSquare()
    

    Calling Kotlin from Java - Kotlin Programming Languagekotlinlang.org

相关文章

网友评论

    本文标题:Kotlin Basic Learning - series 3

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