Kotlin中“with”的意思是什么?

时间:2017-08-25 01:43:03

标签: 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)
        }
    }
}

5 个答案:

答案 0 :(得分:11)

documentation说:

  

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

     

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

我想到的方式是它调用一个函数(blockthis范围内的blockreceiver。 无论block返回什么是返回类型。

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

以下是一个示例:

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

在这种情况下,rec是函数调用的接收器 - this范围内的block$lengthlastIndexOf都在接收方上被调用。

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

答案 1 :(得分:5)

with的定义:

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

实际上它的实现是直截了当的:blockreceiver上执行,适用于任何类型:

receiver.block() //that's the body of `with`

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

在您的示例中,以这种方式访问​​context接收者with的{​​{1}}。

除了appwith之类的stdlib函数之外,此功能使Kotlin非常适合编写特定于域的语言,因为它允许创建您可以访问的范围关于某些功能。

答案 2 :(得分:4)

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
}

答案 3 :(得分:1)

val citizen2 = Citizen("Tom", 24, "Washington")

val age = with(citizen2) {
    println("$name -  $age  $residence ")
    age = this.age + age
    residence = "Florida"
    age+10 // returns 58
}
println("${citizen2.name} -  ${citizen2.age} - $age - ${citizen2.residence}  ")

data class Citizen(var name: String, var age: Int, var residence: String)

输出:

Tom -  24  Washington 
Tom -  48 - 58 - Florida

请注意:

  • 我们可以使用 this.age age
  • 访问市民(接收者对象)的年龄属性 with()的lambda中的
  • 最后一行(在此示例中为 age + 10 )返回。

答案 4 :(得分:0)

With用于将多个操作应用于对象或访问对象的方法,例如在此示例中,我们正在访问String的capitalize()扩展方法

data class Person(val name:String)
fun main(){
   val person = Person("john doe")
    with(person.name) {
       println(this.capitalize()) // output John Doe
    }

}

具有的功能是高级功能。在这里,我们用Person名称说的是大写()。我们实际上并不需要'this',因为它是隐式的并且可以删除