美文网首页Kotlin
Kotlin 入门(五):其他知识点总结

Kotlin 入门(五):其他知识点总结

作者: 孤独的根号十二 | 来源:发表于2019-02-19 16:31 被阅读19次

    This表达式

    为了表示当前的 接收者 我们使用 this 表达式:
    1.在类的成员中, this 指的是该类的当前对象 在扩展函数或者带接收者的函数字面值中, this 表示在点左侧传递的 接收者 参数。
    如果 this 没有限定符,它指的是最内层的包含它的作用域。要引用其他作用域中的 this ,请使用 标签限定符:

    限定的this:

    要访问来自外部作用域的 this (一个类 或者扩展函数, 或者带标签的带接收者的函数字面 值)我们使用 this@label ,其中 @label 是一个 代指 this 来源的标签:

    class A{    //  隐式标签    @A              
    inner classB {  //  隐式标签    @B  
    fun Int.foo()   {   //  隐式标签    @foo
    val a   =   this@A  //  A   的   this    
    val b   =   this@B  //  B   的   this
    val c   =   this    //  foo()   的接收者,一个 Int
    val c1  =   this@foo    //  foo()   的接收者,一个 Int
    val funLit  =   lambda@ fun String.()   {
    val d   =   this    //  funLit  的接收者
    }
    val funLit2 =   {s: String  ->
    //  foo()   的接收者,因为它包含的 lambda  表达式
    //  没有任何接收者
    val d1  =   this
    }}
    } 
    }
    

    相等性

    Kotlin中有两种类型的相等性:
    1.引用相等(两个引用指向同一对象)
    2.结构相等(用equals()检查)

    引用相等

    引用相等由 ===(以及其否定形式 !== )操作判断。 a===b 当且仅当 a和b指向同 一个对象时求值为true。

    结构相等

    结构相等由 == (以及其否定形式 != )操作判断。按照惯例,像 a == b 这样的表达式会 翻译成

    a?.equals(b)    ?:  (b  === null)
    

    也就是说如果 a 不是 null 则调用 equals(Any?) 函数,否则(即 a 是 null )检查 b 是否与 null 引用相等。

    操作符符重载

    Kotlin 允许我们为自己的类型提供预定义的一组操作符的实现。这些操作符具有固定的符号表 示 (如 + 或 * )和固定的优先级。为实现这样的操作符,我们为相应的类型(即二元操作 符左侧的类型和一元操作符的参数类型)提供了一个固定名字的成员函数 或扩展函数。 重载 操作符的函数需要用 operator 修饰符标记。
    重载++:

    class MyTest (var a:Int) {
        operator fun inc():MyTest{
            this.a++
           return this
        }
    }
    

    一元操作

    1. +a 翻译为 a.unaryPlus()
    2. -a 翻译为 a.unaryMinus()
    3. !a 翻译为 a.not()
      注意:以上表达式的返回值可以是任意类型,如果函数存在且其返回类型为R ,那就表达式+a具有类型R

    4.a++/++a 翻译为 a.inc()
    5.a--/--a 翻译为 a.dec()
    注意:以上表达式的返回值必须是a的数据类型或是其子类型。
    a++/++a的区别在于重载函数中是先返回还是先相加

    二元操作

    1. a + b 翻译为 a.plus(b)
    2. a -b 翻译为 a.minus(b)
    3. a * b 翻译为 a.times(b)
    4. a / b 翻译为 a.div(b)
    5. a % b 翻译为 a.rem(b)
    6. a..b 翻译为 a.rangeTo(b)
    7. a in b 翻译为 b.contains(a)
    8. a !in b 翻译为 !b.contains(a)
    9. a[i_1, ……, i_n] 翻译为 a.get(i_1, ……, i_n)
    10. a[i_1, ……, i_n] = b 翻译为 a.set(i_1, ……, i_n, b)
    11. a(i_1, ……, i_n) 翻译为 a.invoke(i_1, ……, i_n)
    12. a += b 翻译为 a.plusAssign(b)
      a -= b 翻译为 a.minusAssign(b)
      a *= b 翻译为 a.timesAssign(b)
      a /= b 翻译为 a.divAssign(b)
      a %= b 翻译为 a.modAssign(b)
    13. a > b 翻译为 a.compareTo(b) > 0
      a < b 翻译为 a.compareTo(b) < 0
      a >= b 翻译为 a.compareTo(b) >= 0
      a <= b 翻译为 a.compareTo(b) <= 0

    注解

    注解声明

    annotation  class   Fancy
    //带参数
    annotation  class   Special(val why:    String)
    允许的参数类型有:
    对应于 Java    原生类型的类型(Int、    Long等);
    字符串; 类( Foo::class  );
     枚举; 其他注解;
    上面已列类型的数组。
    
    注解参数不能有可空类型,因为  JVM 不支持将null作为  注解属性的值存储。
    如果注解用作另一个注解的参数,则其名称不以@字符为前缀:
    annotation class ReplaceWith(val expression: String)
    annotation  class   Deprecated( val message: String,val replaceWith: ReplaceWith = ReplaceWith(""))
    @Deprecated("This   function    is  deprecated, use === instead",   ReplaceWith("this   === othe r"))
    
    如果需要将一个类指定为注解的参数,请使用 Kotlin 类
    (KClass)。Kotlin 编译器会自动将其转换为 Java 类,以便 Java  代码能够正常看到该注解和参数 。
    import  kotlin.reflect.KClass
    annotation  class   Ann(val arg1: KClass<*>, val arg2:  KClass<out Any?>)
    @Ann(String::class, Int::class) class MyClass
    
    
    

    注解的附加属性可以通过用元注解标注注解类来指定:
    1.@Target 指定可以用 该注解标注的元素的可能的类型(类、函数、属性、表达式等);
    2.@Retention 指定该注解是否 存储在编译后的 class 文件中,以及它在运行时能否通过反 射可见 (默认都是 true);
    3.@Repeatable 允许 在单个元素上多次使用相同的该注解;
    4.@MustBeDocumented 指定 该注解是公有 API 的一部分,并且应该包含在 生成的 API 文档 中显示的类或方法的签名中。

    反射

    反射是这样的一组语言和库功能,它允许在运行时自省你的程序的结构。 Kotlin 让语言中的 函数和属性做为一等公民、并对其自省(即在运行时获悉 一个名称或者一个属性或函数的类 型)与简单地使用函数式或响应式风格紧密相关。

    类引用

    最基本的反射功能是获取 Kotlin 类的运行时引用。要获取对 静态已知的 Kotlin 类的引用,可 以使用 类字面值 语法:

    val c   =   MyClass::class
    

    该引用是 KClass 类型的值。 请注意,Kotlin 类引用与 Java类引用不同。要获得 Java类引用, 请在 KClass实例上使用.java属性。

    可以用相同的::class语法获取指定对象的类的引用:

    val widget: Widget  = …… 
    assert(widget   is  GoodWidget) { "Bad widget:${widget::class.qualifiedName}"   }
    

    函数引用

    fun isOdd(x:    Int)    =   x   %   2   !=  0
    val numbers =   listOf(1,   2,  3) 
    println(numbers.filter(::isOdd))
    
    val predicate:(String)  ->  Boolean =   ::isOdd 
    //  引用到 isOdd(x:    String)
    
    

    属性引用

    var x   =   1
    fun main(args:  Array<String>)  {
    println(::x.get())  //  输出  "1"         
    ::x.set(2)  
    println(x)  
    //  输出  "2" 
    }
    

    表达式 ::x 求值为 KProperty<Int> 类型的属性对象,它允许我们使用 get() 读取它的 值,或者使用 name 属性来获取属性名

    class A(val p:  Int)
    fun main(args: Array<String>)   {
    val prop    =   A::p            
    println(prop.get(A(1))) //  输出  "1"
     }
    
    

    与Java反射的互操作性

    在Java平台上,标准库包含反射类的扩展,它提供了与 Java 反射对象之间映射(参见 kotlin.reflect.jvm 包)。 例如,要查找一个用作 Kotlin 属性 getter 的 幕后字段或 Java方 法,可以这样写:

    import  kotlin.reflect.jvm.*
    class   A(val   p:  Int)
    fun main(args:  Array<String>)  {
    println(A::p.javaGetter)    //  输出  "public final   int A.getP()"   
    println(A::p.javaField)     //  输出  "private    final   int A.p" 
    }
    
    

    要获得对应于 Java 类的 Kotlin 类,请使用 .kotlin 扩展属性:

    fun getKClass(o:    Any):KClass<Any>    =o.javaClass.kotlin
    
    

    构造函数引用

    构造函数可以像方法和属性那样引用。他们可以用于期待这样的函数类型对象的任何 地方: 它与该构造函数接受相同参数并且返回相应类型的对象。 通过使用 :: 操作符并添加类名来 引用构造函数。考虑下面的函数, 它期待一个无参并返回 Foo 类型的函数参数:

    class   Foo
    fun function(factory:   ()  ->  Foo)    {   
    val x:  Foo =   factory()
     }
    //使用    ::Foo,类 Foo 的零参数构造函数,我们可以这样简单地调用它:
    function(::Foo)
    
    

    相关文章

      网友评论

        本文标题:Kotlin 入门(五):其他知识点总结

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