我们应该何时使用运行的例子,并且应用在Kotlin上
我希望每个函数运行都有一个很好的例子,让我们应用
我读过这篇文章,但还是缺乏一个例子
所有这些函数都用于切换当前函数/变量的范围。 它们被用来把那些属于同一个地方的东西(主要是初始化)保存在一起。
这里有些例子:
run
– 返回你想要的任何东西,并重新定义它所使用的变量
val password: Password = PasswordGenerator().run { seed = "someString" hash = {s -> someHash(s)} hashRepetitions = 1000 generate() }
现在密码生成器被重新设置为this
,因此我们可以设置seed
, hash
和hashRepetitions
而不使用变量。 generate()
将返回一个Password
的实例。
apply
是相似的,但它会返回this
:
val generator = PasswordGenerator().apply { seed = "someString" hash = {s -> someHash(s)} hashRepetitions = 1000 } val pasword = generator.generate()
作为Builder模式的替代品,如果你想重新使用某些配置,这是特别有用的。
let
– 主要用于避免空检查,但也可以用作run
的替代品。 不同之处在于, this
仍然和以前一样,并使用it
访问重新定义的变量:
val fruitBasket = ... apple?.let { println("adding a ${apple.color} apple!") fruitBasket.add(it) }
上面的代码将添加到篮子只有当它不是null。 另外注意,现在it
不再是可选的了,所以你不会在这里遇到一个NullPointerException(也就是说,你不需要使用?.
来访问它的属性)
also
– 使用它,当你想使用apply
,但不想影响this
class FruitBasket { private var weight = 0 fun addFrom(appleTree: AppleTree) { val apple = appleTree.pick().also { apple -> this.weight += apple.weight add(apple) } ... } ... fun add(fruit: Fruit) = ... }
在这里使用apply
会影响this
,所以this.weight
会指苹果,而不是水果篮。
注:我无耻地从我的博客中拿出了例子
还有一些像这样的文章, 这里值得一看。
我认为,当你需要更短,更简洁的几行,并避免分支或条件语句检查(如非空,则这样做)。
我喜欢这个简单的图表,所以我把它链接到这里。 你可以从Sebastiano Gottardo的书中看到它。
请看下面的解释。
概念
当你调用这些函数时,我认为这是你的代码块中扮演的角色,无论你是否希望自己回到链接调用函数或设置为结果变量等。
以上是我的想法。
概念例子
让我们看看这里所有的例子
1.) myComputer.apply { }
意味着你想扮演一个主角(你想认为你是电脑),并且你想让自己回来(电脑),所以你可以做
var crashedComputer = myComputer.apply { // you're the computer, you yourself install the apps // note: installFancyApps is one of methods of computer installFancyApps() }.crash()
是的,你自己只是安装应用程序,崩溃自己,并保存自己作为参考,以允许他人看到和做一些事情。
2.) myComputer.also {}
意味着你完全确定你不是电脑,你是外人想要做的事情,也希望它的计算机作为返回的结果。
var crashedComputer = myComputer.also { // now your grandpa does something with it myGrandpa.installVirusOn(it) }.crash()
3.) with(myComputer) { }
表示你是主要演员(电脑),你不希望你自己回来。
with(myComputer) { // you're the computer, you yourself install the apps installFancyApps() }
4.) myComputer.run { }
表示你是主要的演员(电脑),你不希望你自己回来。
myComputer.run { // you're the computer, you yourself install the apps installFancyApps() }
但with { }
的不同之处在于,您可以像以下那样链接调用run { }
myComputer.run { installFancyApps() }.run { // computer object isn't passed through here. So you cannot call installFancyApps() here again. println("woop!") }
这是由于run {}
是扩展函数,但with { }
不是。 所以你调用run { }
, this
代码块里面的this
对象就会被调用。 你可以看到这是一个很好的解释run {}
和with {}
之间的区别。
5.) myComputer.let { }
表示你是局外人,看着电脑,想要做一些事情,而不用担心电脑实例再次返回给你。
myComputer.let { myGrandpa.installVirusOn(it) }
看它的方式
我也倾向于看,并作为外部,外部的东西。 每当你说出这两个字时,就像你试图在某个事物上采取行动一样。 let
这台电脑上安装病毒, also
崩溃。 因此,这是否是演员的一部分。
对于结果部分来说,显然是存在的。 also
表示这也是另一回事,所以你仍然保留对象本身的可用性。 因此它返回它作为结果。
一切都与this
相关联。 另外run/with
显然没有兴趣返回对象自己回来。 现在你可以区分所有这些。
我认为有时候,当我们从100%编程/基于逻辑的例子中走出来,那么我们就可以更好地概念化事物。 但是,这取决于:)