【问题标题】:Property references vs. lambdas for getter/settergetter/setter 的属性引用与 lambdas
【发布时间】:2020-07-18 09:14:51
【问题描述】:

我需要从方法中获取和设置另一个类的属性,因此需要为 getter 和 setter 传入 lambda 的属性引用:

  1. 传入属性引用

    otherInstance::property

  2. 为 getter 传入一个 lambda,为 setter 传入一个:

    {otherInstance.property} // getter

    {value -> otherInstance.property = value} // setter

我喜欢第一个,因为对我来说代码更容易阅读且更短,但是当我在 official documentation 上看到它时,我的警钟会响起,因为“反射”一词。我对 Java 的了解是,反射通常不是一件好事。这对 Kotlin 也有效吗?在这种情况下有效吗?两种方式中的一种(属性引用或 lambda)是否更高效或更安全?

【问题讨论】:

    标签: kotlin lambda reflection properties


    【解决方案1】:

    文档是关于成员引用和反射

    如果您指的是不使用反射本身的属性引用

    反射只在不同的部分引用Obtaining member references from a class reference

    动态检查对象以查看例如它包含哪些属性和函数以及它们上存在哪些注释。这称为反射,它的性能不是很好,所以除非你真的需要它,否则请避免它。

    Kotlin 有自己的反射库(kotlin-reflect.jar 必须包含在您的构建中)。以 JVM 为目标时,您还可以使用 Java 反射工具。请注意,Kotlin 反射功能还不够完善 - 特别是,您不能使用它来检查像 String 这样的内置类。

    【讨论】:

    • 属性引用可用于反射。您可以使用KMutableProperty 来获取注释、属性名称以及声明的属性的各种特征。
    • @Tenfour04 但是属性引用没有使用反射结果是一个对象,它表示对属性的引用(“柏拉图式理想”属性,而不是特定实例上的属性)
    • 我想这取决于“反射”的含义。如果仅仅是内省代码的能力,那么KProperty 就符合这个定义。无论如何,如果 OP 的函数需要引用来实际调用,它们将需要来自特定实例的属性 (KMutableProperty1),而不是柏拉图式的理想版本 (KMutableProperty)。
    【解决方案2】:

    通过使用KMutableProperty0,从技术上讲,您将公开一个可用于反射的对象。如果您想严格避免反射,您可以对 getter 和 setter 使用单独的函数引用。请注意,不必将 lambda 作为函数引用传递给高阶函数。如果有效签名匹配,编译器可以将属性引用解释为函数。不幸的是,这意味着必须两次传递属性引用。不幸的是,在这种情况下,必须通过技术反射来检索 setter:

    class Test (var x: Int)
    
    fun foo(getter: () -> Int, setter: (Int) -> Unit) {
        //...
    }
    
    val test = Test(1)
    foo(test::x, test::x.setter)
    
    // Zero reflection call:
    foo(test::x) { test.x = it }
    

    在某些时候你不得不质疑你想避免反射有多严重,因为上面的代码在我看来非常混乱。如果您的类采用KMutableProperty0 引用,则使用起来会简单得多。只要您的接收函数没有使用引用来自省代码,并且只在其上调用get()set(),那么您并没有真正以应避免的方式使用反射。

    fun foo(property: KMutableProperty0<Int>) {
        //...
    }
    
    val test = Test(1)
    foo(test::x)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 2016-05-03
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多