访问外部价值内适用

简短的例子:

class MyClass { val someName = "want this value" val someOther = SomeOther().apply{ someName = someName } // other stuff below } 

SomeOther将它自己的someName值应用到someName ,所以value应用没有什么区别(x = x)。

问:如何访问外部someName“想要这个值” )在里面apply

更新我有进一步的疑虑相关的建议使用this.someName=someName ,下面2代码片断,第一个按预期工作,令人惊讶的是第二个失败与类似的行为描述。

第一

 fun main(args: Array) { class SomeOther { var someName: String? = null } val someName = "want this value" print(SomeOther().apply { this.someName = someName }.someName) // works! } 

第二

 class SomeOther { var someName: String? = null } class MyClass { val someName = "want this value" val someOther = SomeOther().apply { this.someName = someName } fun go() = print(someOther.someName) } fun main(args: Array) = MyClass().go() // prints null 

问:区别在哪里?

你也可以使用alsofunction。 这相当于apply ,除了它将绑定你的对象而不是this

 val someName = "want this value" val someOther = SomeOther().also { it.someName = someName } 

alsofunction被添加到Kotlin 1.1,特别是当你不想从外部的范围中影响this

使用这个参考expression式如下:

 val someOther = SomeOther().apply { someName = this@MyClass.someName } // reference to the outer class ---^ 

T.apply函数是一个方便的方式来应用Builder设计模式 ,这样你永远不需要使用this或额外的参数,例如:

 val foo = Foo().apply { //v--- no need using `this` or any addition parameters foo = "bar" fuzz = "buzz" } class Foo { lateinit var foo: String; lateinit var fuzz: String } 

编辑

你可以假设apply(lambda)将应用一个匿名类Function2实例,那么你知道为什么立即?

在你的第一个方法中,它看起来像下面这样:

 val lambda: Function2 = { thisRef, arg -> thisRef.someName = arg; // ^--- parameter is used in lambda thisRef } val someName = lambda(SomeOther(), "want this value").someName println(someName) 

在你的第二种方法,它看起来像下面这样:

 class MyClass { val lambda: Function2 = { thisRef, arg -> // the parameter `arg` is never used in lambda ---^ thisRef.someName = thisRef.someName // ^--- it use thisRef's someName rather than arg's thisRef } val someOther = lambda(SomeOther(), this) } 

尝试这个:

 val someName = "want this value" val otherName = SomeOther().apply { this.someName = someName } // internal someName ---^ ^ // external someName ---^ print(otherName.someName) // >>> want this name