Kotlin中"with"的意思是什么?

Vla*_*nov 17 kotlin

我已经阅读了3次文档,但我仍然不知道它的作用.有人可以ELI5(解释就像我五岁)吗?这是我使用它的方式:

fun main(args: Array<String>) {
    val UserModel = UserModel()
    val app = Javalin.create().port(7000).start()

    with (app) {
        get("/users") {
            context -> context.json(UserModel)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

mko*_*bit 11

文件说:

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

使用给定的接收器作为接收器调用指定的功能块并返回其结果.

我想到它的方式是它调用一个函数(block),this其范围blockreceiver.无论block返回类型是什么.

基本上调用一个方法,你提供隐式,this并可以从中返回任何结果.

这是一个示例:

val rec = "hello"
val returnedValue: Int = with(rec) {
  println("$this is ${length}")
  lastIndexOf("l")
}
Run Code Online (Sandbox Code Playgroud)

rec这种情况下是接收函数调用的-在this中的范围block.在$lengthlastIndexOf都呼吁接收器.

返回值可以看作是Int因为这是签名中的最后一个方法调用body- 这是R签名的泛型类型参数.


Pau*_*cks 8

with用于访问对象的成员和方法,而不必每次访问都引用该对象一次。(主要是)用于简化您的代码。在构造对象时经常使用它:

// Verbose way, 219 characters:
var thing = Thingummy()
thing.component1 = something()
thing.component2 = somethingElse()
thing.component3 = constantValue
thing.component4 = foo()
thing.component5 = bar()
parent.children.add(thing)
thing.refcount = 1

// Terse way, 205 characters:
var thing = with(Thingummy()) {
  component1 = something()
  component2 = somethingElse()
  component3 = constantValue
  component4 = foo()
  component5 = bar()
  parent.children.add(this)
  refcount = 1
}
Run Code Online (Sandbox Code Playgroud)

  • 简单但还没说到重点。我个人认为,这样的答案比冗长的答案更值得关注。因为 PO 自己明确要求“像我五岁一样解释一下”。不能破坏这个线程中的其他答案,但可以说一件事,简化某件事的能力意味着你已经掌握了要点 (3认同)
  • 这也是指出这鼓励不变性的好时机;第二个“var thing”应该成为“val thing”并保证它永远不会改变,除非你希望它改变 (2认同)
  • @Supuhstar 不变性与此无关。`val` 仅仅意味着,你不能重新分配。这并不意味着您无法更改状态。如果第二个“thing”可以是“val”,那么第一个“thing”也可以是“val” (2认同)

s1m*_*nw1 5

定义with:

inline fun <T, R> with(receiver: T, block: T.() -> R): R (source)
Run Code Online (Sandbox Code Playgroud)

实际上它的实现很简单:block执行时receiver,适用于任何类型:

receiver.block() //that's the body of `with`
Run Code Online (Sandbox Code Playgroud)

这里最值得一提的是参数类型T.() -> R:它被称为带接收器函数文字.它实际上是一个lambda,可以访问接收者的成员而无需任何额外的限定符.

在您的示例中context,以这种方式访问with接收器app.

除了像STDLIB功能with或者apply,此功能是什么使科特林伟大的写作领域特定语言,因为它允许范围内,你必须对某些功能的访问范围的创建.