// More than 30% fewer lines of code compared to Java
// (based on the experience of Duolingo and other companies)
data class Book (
val title: String, // + automatically generated equals(),
val year: Int // hashCode(), toString(), and copy()
)
fun century(year: Int) = (year - 1) / 100 + 1 // Top-level function,
// single-expression body
fun main() {
val books = listOf( // Construct a list
Book("Don Quixote", 1605), // No `new` keyword
Book("The Lord of the Rings", 1955)
)
val classics = books.filter { century(it.year) < 20 } // Trailing single-argument lambda
println("Classic books: $classics") // Calls toString() for Book
}
// Apps built with Kotlin are 20% less likely to crash
// (based on Google's internal data)
fun printMessagesUppercased(messages: List<String?>) { // List elements can be nulls
// messages.add(Message("Java")) // ERROR: List is read-only
messages.onEachIndexed { index, msg ->
print("\nMessage #$index: ")
// print(msg.uppercase()) // ERROR: `msg` can be null
msg?.let { // Print only if `msg` is not null
print(it.uppercase()) // OK, `it` is String
}
}
}
fun main() {
val messages = mutableListOf("hello", null, "world")
// messages = mutableListOf("!!!") // ERROR: can't reassign a value
messages.add("Kotlin") // OK: the list is mutable
printMessagesUppercased(messages) // Pass the list as read-only
}
import kotlin.math.absoluteValue
fun main() {
//sampleStart
val dates = listOf(1 to "January", 13 to "May", 22 to "September", 23 to "December")
dates.forEach { (day, month) -> // Traverse a list of pairs with a trailing lambda
println("${day.ordinal()} of $month") // Use the Int.ordinal() extension function
}
createEmptyWindow()
.apply { // Configure properties of an object
width = 300
height = 200
isVisible = true
}.also { w -> // Perform an additional operation on a call chain
showWindow(w)
}
issueById["13456"]
?.takeIf { it.status == Status.FIXED } // Use the value only if the condition is true
?.let { // Do something only if the value is not null
println("We've fixed this: $it")
}
//sampleEnd
}
// Extension function
fun Int.ordinal() = this.absoluteValue.let { iAbs ->
val suffix = if (iAbs % 100 in 11..13) "th" else
when (iAbs % 10) {
1 -> "st"
2 -> "nd"
3 -> "rd"
else -> "th"
}
"$this$suffix"
}
data class Window(var width: Int, var height: Int, var isVisible: Boolean)
fun createEmptyWindow() = Window(0, 0, false)
fun showWindow(window: Window) {
println("Showing $window")
}
enum class Status { OPEN, FIXED, IN_PROGRESS }
data class Issue(val status: Status)
val issueById = mutableMapOf(
"13456" to Issue(Status.FIXED)
)
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
//sampleStart
// More than 50% of professional developers who use coroutines
// report increased productivity
// (based on Google's internal data)
fun main() = runBlocking {
val start = System.currentTimeMillis()
coroutineScope { // Create a scope for coroutines
val waitingJob = launch { // Launching a coroutine
waiting(start, 150)
}
countdownSignals(10, 300).collect { value -> // Collecting flow elements
log(start, "Countdown: $value")
}
waitingJob.cancel() // Cancelling a coroutine
}
log(start, "Liftoff!") // Execution continues when all
} // coroutines have finished
//sampleEnd
fun countdownSignals(n: Int, delayMillis: Long): Flow<Int> = flow { // Flow builder
for (i in (1..n).reversed()) {
delay(delayMillis) // Delay in emitting signals
emit(i) // Emit the flow element
}
}
// A function that can be suspended and resumed later
suspend fun waiting(start: Long, delayMillis: Long) {
while (currentCoroutineContext().isActive) { // Check coroutine's context
log(start, "Waiting...")
delay(delayMillis) // Waiting concurrently
}
}
fun log(start: Long, msg: String) {
println("$msg after ${(System.currentTimeMillis() - start)/1000F}s")
}
// Use any existing JVM library or framework
// Call Kotlin code from Java without an issue
@SpringBootApplication
class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
@RestController
class MessageResource {
@GetMapping
fun index(): List<Message> = listOf(
Message("1", "Hello!"),
Message("2", "Bonjour!"),
Message("3", "Privet!"),
)
}
data class Message(val id: String?, val text: String)
开始使用 ↗