我们应该何时使用运行的例子,并且应用在Kotlin上

我希望每个函数运行都有一个很好的例子,让我们应用

我读过这篇文章,但还是缺乏一个例子

所有这些函数都用于切换当前函数/变量的范围。 它们被用来把那些属于同一个地方的东西(主要是初始化)保存在一起。

这里有些例子:

run – 返回你想要的任何东西,并重新定义它所使用的变量

 val password: Password = PasswordGenerator().run { seed = "someString" hash = {s -> someHash(s)} hashRepetitions = 1000 generate() } 

现在密码生成器被重新设置为this ,因此我们可以设置seedhashhashRepetitions而不使用变量。 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%编程/基于逻辑的例子中走出来,那么我们就可以更好地概念化事物。 但是,这取决于:)