2017-08-25 29 views
13

Tôi đã đọc tài liệu trên đó 3 lần và tôi vẫn không biết nó làm gì. Có thể một người nào đó ELI5 (Giải thích giống như tôi là năm) không? Đây là cách tôi đang sử dụng nó:"with" có nghĩa là gì trong Kotlin?

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

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

Wow, câu hỏi của bạn khiến tôi nhận ra rằng không có tài liệu hay về những gì làm cho 'với' - là một hàm **, chứ không phải từ khóa - thực sự hoạt động! Vì vậy, tôi đã viết một câu hỏi và trả lời nó cùng loại, có thể nó sẽ thêm một số giá trị cho các câu trả lời đã tồn tại. Xem: [Một "người nhận" ở Kotlin là gì?] (Https://stackoverflow.com/q/45875491/7079453) –

+1

Bạn vẫn đang chờ câu trả lời? ;-) – s1m0nw1

Trả lời

9

Các documentation nói:

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

Calls khối chức năng xác định với thu cho là nhận và trả kết quả của nó.

Con đường tôi nghĩ về nó là nó đang kêu gọi một chức năng (các block), nơi this trong phạm vi của blockreceiver. Bất kể số tiền trả về là block là loại trả về.

Về cơ bản gọi phương thức mà bạn cung cấp ngụ ý this và có thể trả về bất kỳ kết quả nào từ nó.

Dưới đây là một ví dụ để chứng minh:

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

Các rec trong trường hợp này là nhận của cuộc gọi chức năng - những this trong phạm vi của block. Các số $lengthlastIndexOf đều được gọi trên máy thu.

Giá trị trả về có thể được xem là Int vì đó là cuộc gọi phương thức cuối cùng trong body - đó là thông số loại chung R chữ ký.

+0

Vì vậy, nó chỉ là một công cụ để nói những gì phạm vi bạn muốn được ở? –

+1

@VladyVeselinov về cơ bản, vâng. Có một vài chức năng phạm vi khác có thể giúp bạn mã rõ ràng hơn. Bạn có thể xem một số ví dụ và thảo luận về các mẫu sử dụng chung trong kho lưu trữ [yole/kotlin-style-guide GitHub] (https://github.com/yole/kotlin-style-guide/issues/35). – mkobit

2

with được sử dụng để truy cập các thành viên và phương thức của đối tượng mà không cần phải tham chiếu đối tượng một lần cho mỗi lần truy cập. Đó là (chủ yếu) để viết tắt mã của bạn. Nó thường được sử dụng khi xây dựng một đối tượng:

// 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

Đây cũng là thời điểm tuyệt vời để chỉ ra rằng điều này khuyến khích sự bất biến; 'var điều' thứ hai sẽ trở thành một' val điều' và đảm bảo nó không bao giờ thay đổi trừ khi bạn muốn nó thay đổi – Supuhstar

5

Định nghĩa của with:

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

Trên thực tế nó là thực hiện được thẳng về phía trước: Các block được thực thi trên receiver, mà làm việc cho bất kỳ loại:

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

Điều tuyệt vời cần đề cập ở đây, là loại thông số T.() -> R: Nó được gọi là function literal with receiver. Nó thực sự là lambda có thể truy cập các thành viên của người nhận mà không cần thêm bất kỳ vòng loại bổ sung nào.

Trong ví dụ của bạn, context của with bộ thu app được truy cập theo cách đó.

Bên cạnh chức năng stdlib như with hoặc apply, chức năng này là những gì làm Kotlin tuyệt vời cho văn bản miền Ngôn ngữ cụ thể vì nó cho phép tạo ra các phạm vi mà trong đó bạn có thể truy cập vào các chức năng nhất định.