以下是我用来消除现有片段的代码。我能够使用let
和apply
。我读了很多关于let
和apply
之间差异的文章,我明白:
- apply修改我们现有的对象
- let创建对象的副本并可以对其进行修改。如果我们退出
let
范围,则原始对象是完整的。我说得对吗
我的代码有两个版本。
private fun prepareQuestionFragment(indexOfMarkerList: Int): QuestionFragment {
childFragmentManager.findFragmentByTag(QuestionFragment.TAG)?.apply {
this as QuestionFragment
this.dismissAllowingStateLoss()
}
return QuestionFragment.newInstance(indexOfMarkerList)
}
private fun prepareQuestionFragment(indexOfMarkerList: Int): QuestionFragment {
childFragmentManager.findFragmentByTag(QuestionFragment.TAG)?.let {
it as QuestionFragment
it.dismissAllowingStateLoss()
}
return QuestionFragment.newInstance(indexOfMarkerList)
}
这种情况有什么不同?对我来说,他们的行为是一样的。
let
是否复制了Fragment?如果是这样的话,我们将忽略片段的副本,并且原始片段应该保持可见。我是不是错过了什么?let
和apply
是否仍然包含对对象的引用(而不是副本(?
let创建对象的副本并可以对其进行修改。如果我们退出let范围,原始对象将保持不变。我说得对吗?
否。Java/Kotlin没有复制对象的通用概念。它们只能复制对同一对象的引用。
示例中的主要区别在于lambda如何接收QuestionFragment
对象。let()
中的Lambda将QuestionFragment
作为其常规参数,默认情况下命名为it
。apply()
中的Lambda接收此对象作为其接收器自变量,因此this
。这几乎是表面上的区别,在工作方式上并没有真正的区别。
另一个区别是let()
返回lambda的结果,因此在您的示例中是dismissAllowingStateLoss()
的结果。apply()
返回接收器对象,因此返回findFragmentByTag()
的结果。您没有使用let()
/apply()
的返回值,因此此差异在您的示例中无关紧要。