首页 > 其他分享 >Kotlin常用函数 let,with,apply,also,run

Kotlin常用函数 let,with,apply,also,run

时间:2022-11-04 12:05:26浏览次数:67  
标签:u0002 run u0010 Kotlin also str main public block


前言

kotlin 开发中常用的几个函数,let,with,run,apply,also ,他们都是范围函数,具体使用场景迷糊,开发中不知道如何使用。这里罗列出来泛型表达式,反编译之后字节码进行对比,方便记忆

函数名

定义inline的结构

函数体内使用的对象

返回值

是否是扩展函数

适用的场景

let

fun <T, R> T.let(block: (T) -> R): R = block(this)

it指代当前对象

闭包


适用于处理不为null的操作场景

with

fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

this指代当前对象或者省略

闭包


类对象连续调用类属性和方法的位置

run

fun <T, R> T.run(block: T.() -> R): R = block()

this指代当前对象或者省略

闭包


适用于let,with函数任何场景。

apply

fun T.apply(block: T.() -> Unit): T { block(); return this }

this指代当前对象或者省略

this


builder模式使用地方

also

fun T.also(block: (T) -> Unit): T { block(this); return this }

it指代当前对象

this


builder模式使用地方

注意kotlin lambda语法:

block: (T) -> R lambda 表达式声明。
block: T.() -> R 带接收者的lambda表达式声明,这种写法可以在 block 中使用 this 关键字代表 T实参 使用

fun main() {

val str=123
//① val combinStr=str.let { "$str world" }
//② val combinStr= with(str) {
// "$str world"
// }
//③ val combinStr=str.run { "$str world " }

//④ val combinStr=str.apply { "$str world" }

//⑤ val combinStr=str.also { "$str world" }
println(combinStr)

}

//泛型 T/R, [入参T返回 R]

//① fun <T, R> T.let(block: (T) -> R): R = block(this)
//② fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
//③ fun <T, R> T.run(block: T.() -> R): R = block()
//④ fun T.apply(block: T.() -> Unit): T { block(); return this }
//⑤ fun T.also(block: (T) -> Unit): T { block(this); return this }
let
//① fun <T, R> T.let(block: (T) -> R): R = block(this)

fun main() {
val str=123
val combinStr=str.let { "$str world" }
println(combinStr)
}


package letrunwithalsoapply;

import kotlin.Metadata;
import kotlin.jvm.functions.Function1;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
mv = {1, 6, 0},
k = 2,
xi = 2,
d1 = {"\u0000\u0012\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0004\n\u0002\u0018\u0002\n\u0002\b\u0002\u001a\u0006\u0010\u0000\u001a\u00020\u0001\u001a/\u0010\u0002\u001a\u0002H\u0003\"\u0004\b\u0000\u0010\u0004\"\u0004\b\u0001\u0010\u0003*\u0002H\u00042\u0012\u0010\u0005\u001a\u000e\u0012\u0004\u0012\u0002H\u0004\u0012\u0004\u0012\u0002H\u00030\u0006¢\u0006\u0002\u0010\u0007¨\u0006\b"},
d2 = {"main", "", "let", "R", "T", "block", "Lkotlin/Function1;", "(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;", "untitled2"}
)
public final class LetRunAlsoWithApplyKt {
public static final void main() {
final int str = 123;
String combinStr = (String)let(Integer.valueOf(str), (Function1)(new Function1() {
// $FF: synthetic method
// $FF: bridge method
public Object invoke(Object var1) {
return this.invoke(((Number)var1).intValue());
}

@NotNull
public final String invoke(int it) {
return str + " world";
}
}));
System.out.println(combinStr);
}

// $FF: synthetic method
public static void main(String[] var0) {
main();
}

public static final Object let(Object $this$let, @NotNull Function1 block) {
Intrinsics.checkNotNullParameter(block, "block");
return block.invoke($this$let);
}

}

with
//② fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

fun main() {
val str=123
val combinStr= with(str) {
"$str world"
}
println(combinStr)
}



package letrunwithalsoapply;

import kotlin.Metadata;
import kotlin.jvm.functions.Function1;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
mv = {1, 6, 0},
k = 2,
xi = 2,
d1 = {"\u0000\u0016\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u001a\u0006\u0010\u0000\u001a\u00020\u0001\u001a8\u0010\u0002\u001a\u0002H\u0003\"\u0004\b\u0000\u0010\u0004\"\u0004\b\u0001\u0010\u00032\u0006\u0010\u0005\u001a\u0002H\u00042\u0017\u0010\u0006\u001a\u0013\u0012\u0004\u0012\u0002H\u0004\u0012\u0004\u0012\u0002H\u00030\u0007¢\u0006\u0002\b\b¢\u0006\u0002\u0010\t¨\u0006\n"},
d2 = {"main", "", "with", "R", "T", "receiver", "block", "Lkotlin/Function1;", "Lkotlin/ExtensionFunctionType;", "(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;", "untitled2"}
)
public final class LetRunAlsoWithApplyKt {
public static final void main() {
final int str = 123;
String combinStr = (String)with(Integer.valueOf(str), (Function1)(new Function1() {
// $FF: synthetic method
// $FF: bridge method
public Object invoke(Object var1) {
return this.invoke(((Number)var1).intValue());
}

@NotNull
public final String invoke(int $this$with) {
return str + " world";
}
}));
System.out.println(combinStr);
}

// $FF: synthetic method
public static void main(String[] var0) {
main();
}

public static final Object with(Object receiver, @NotNull Function1 block) {
Intrinsics.checkNotNullParameter(block, "block");
return block.invoke(receiver);
}
}
run
```kotlin

//③ fun <T, R> T.run(block: T.() -> R): R = block()

fun main() {
val str=123
val combinStr=str.run { "$str world " }
println(combinStr)
}



package letrunwithalsoapply;

import kotlin.Metadata;
import kotlin.jvm.functions.Function1;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
mv = {1, 6, 0},
k = 2,
xi = 2,
d1 = {"\u0000\u0016\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0004\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u001a\u0006\u0010\u0000\u001a\u00020\u0001\u001a4\u0010\u0002\u001a\u0002H\u0003\"\u0004\b\u0000\u0010\u0004\"\u0004\b\u0001\u0010\u0003*\u0002H\u00042\u0017\u0010\u0005\u001a\u0013\u0012\u0004\u0012\u0002H\u0004\u0012\u0004\u0012\u0002H\u00030\u0006¢\u0006\u0002\b\u0007¢\u0006\u0002\u0010\b¨\u0006\t"},
d2 = {"main", "", "run", "R", "T", "block", "Lkotlin/Function1;", "Lkotlin/ExtensionFunctionType;", "(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;", "untitled2"}
)
public final class LetRunAlsoWithApplyKt {
public static final void main() {
final int str = 123;
String combinStr = (String)run(Integer.valueOf(str), (Function1)(new Function1() {
// $FF: synthetic method
// $FF: bridge method
public Object invoke(Object var1) {
return this.invoke(((Number)var1).intValue());
}

@NotNull
public final String invoke(int $this$run) {
return str + " world ";
}
}));
System.out.println(combinStr);
}

// $FF: synthetic method
public static void main(String[] var0) {
main();
}

public static final Object run(Object $this$run, @NotNull Function1 block) {
Intrinsics.checkNotNullParameter(block, "block");
return block.invoke($this$run);
}
}
apply
//④ fun T.apply(block: T.() -> Unit): T { block(); return this }

fun main() {
val str=123
val combinStr=str.apply { "$str world" }
println(combinStr)
}


import kotlin.Metadata;

@Metadata(
mv = {1, 6, 0},
k = 2,
xi = 2,
d1 = {"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
d2 = {"main", "", "untitled2"}
)
public final class LetRunAlsoWithApplyKt {
public static final void main() {
int str = 123;
int var4 = false;
(new StringBuilder()).append(str).append(" world").toString();
System.out.println(str);
}

// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
also
//⑤fun T.also(block: (T) -> Unit): T { block(this); return this }

fun main() {
val str=123
val combinStr=str.also { "$str world" }
println(combinStr)
}



package letrunwithalsoapply;

import kotlin.Metadata;

@Metadata(
mv = {1, 6, 0},
k = 2,
xi = 2,
d1 = {"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
d2 = {"main", "", "untitled2"}
)
public final class LetRunAlsoWithApplyKt {
public static final void main() {
int str = 123;
int var4 = false;
(new StringBuilder()).append(str).append(" world").toString();
System.out.println(str);
}

// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
总结

基本上 apply 和 with 所做的事情就是对提供给它的接收者调用扩展函数类型的参数。 apply 函数被声明为这个接收者的扩展函数,而 with 函数把却把它作为第一个参数。另外 , apply 返回接收者本身 ,而 with 返回调用 lambda 后的结果。如果你并不关心返回值,这两个方式是可以互换使用

​​Kotlin系列之let、with、run、apply、also函数的使用​​this还是it?合理使用with操作符


标签:u0002,run,u0010,Kotlin,also,str,main,public,block
From: https://blog.51cto.com/u_15861646/5823433

相关文章

  • kotlin 注解声明与使用
    前言函数的调用需要知道函数所在的类,函数的入参个数和参数类型,注解和反射可以跳过这个限制,注解和反射可以编写事先未知的任意类代码。注解可以为类库赋予特定的语义,反射可以......
  • Android kotlin泛型知识点梳理
    前言学习知识需要提前设立目标,带着问题学习才能有的放矢。无论是java的泛型还是kotlin语言的泛型均是写框架,写通用工具类神器。如果不熟悉泛型语法,开发过程中将会遇到很多奇......
  • Android kotlin 类委托 by,by lazy关键
    前言接触kotlin语言也有几年时间了。日常开发工作中也推荐使用kotlin,但是对于一些kotlin语言语法的细节没有进行系统学习。碎片的知识点让工作中屡屡碰壁,前些天开始学习comp......
  • pycharm报错:RuntimeError: DataLoader worker (pid(s) 15316, 3652, 22168, 24852) ex
    解决方法有两个: 方案1:定位到d2l文件夹下的torch.py文件,找到 get_dataloader_workers() 函数:#Definedinfile:./chapter_linear-networks/image-classification-d......
  • Time to Run
    ​​D-TimetoRun​​​​CodeforcesRound#619(Div.2)Editorial​​特别要考虑到只有一行或者只有一列的情况。如果由k直接正向推路径的话,难免会要考虑到很多种情......
  • spring-boot-2.0.3启动源码篇四 - run方法(三)之createApplicationContext
    前言此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事。如果大家对springboot的源码有所研究,可以挑些自己感兴趣或者对自......
  • spring-boot-2.0.3启动源码篇三 - run方法(二)之prepareEnvironment
    前言此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事。如果大家对springboot的源码有所研究,可以挑些自己感兴趣或者对自......
  • spring-boot-2.0.3启动源码篇五 - run方法(四)之prepareContext
    前言此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事。如果大家对springboot的源码有所研究,可以挑些自己感兴趣或者对自......
  • Runtime类
     publicclassRuntimeDemo{publicstaticvoidmain(String[]args)throwsIOException{//获取Runtime类对象Runtimeruntime=Runtime.ge......
  • hive的trunc函数详解
    一、日期TRUNC函数为指定元素而截去的日期值。其具体的语法格式:TRUNC(date[,fmt])其中:date一个日期值fmt日期格式,该日期将由指定的元素格式所截去。忽略它则由最......