2017-08-25 44 views
13

我已經閱讀了3次文檔,但我仍然不知道它的功能。可以有人ELI5(請解釋我是五)嗎?下面是我如何使用它:Kotlin中的「with」是什麼意思?

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

    with (app) { 
     get("/users") { 
      context -> context.json(UserModel) 
     } 
    } 
} 
+3

哇,你的問題讓我意識到沒有好的文檔說明什麼使'with'成爲**功能**,而不是關鍵字 - 實際上是工作的!所以我寫了一個問題,並以相同的類型回答它,也許它會爲已有的答案增加一些價值。請參閱:[什麼是Kotlin的「接收器」?](https://stackoverflow.com/q/45875491/7079453) –

+1

您還在等待答案嗎? ;-) – s1m0nw1

回答

9

documentation說:

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

調用指定的功能塊與給定的接收器爲它的接收器並返回其結果。

我認爲它的方式是,它被調用函數(block),其中thisblock的範圍是receiver。 無論block返回的是返回類型。

基本上調用一個方法,您提供隱含的this並可以返回任何結果。

下面是一個例子來說明:

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

在這種情況下的rec是函數調用的接收機 - 在block的範圍this。接收機上都會調用$lengthlastIndexOf

返回值可以被看作是一個Int因爲這是在body最後一個方法調用 - 這就是簽名的泛型類型參數R

+0

所以它只是一個說明你想要在什麼範圍內的工具? –

+1

@VladyVeselinov本質上,是的。還有一些其他的範圍函數可以幫助你更清晰的代碼。你可以在[yole/kotlin-style-guide GitHub repository](https://github.com/yole/kotlin-style-guide/issues/35)中看到一些關於一般用法模式的例子和討論。 – mkobit

2

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 
} 
+0

這也是指出這鼓勵不變性的好時機;第二個'var thing'應該成爲'val thing'並且保證它永遠不會改變,除非你想改變它 – Supuhstar

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,它可以在沒有任何附加限定符的情況下訪問接收者的成員。

在你的例子中,contextwith接收器app以這種方式被訪問。

除了像withapply STDLIB功能,此功能是什麼使科特林偉大的寫作領域特定語言,因爲它允許範圍內,你必須對某些功能的訪問範圍的創建。