Learning materials
学习资料
Overview
概述
You can use the following materials and resources for learning Kotlin:
您可以使用下述文档和资源学习 Kotlin:
- Basic syntax – get a quick overview of the Kotlin syntax.
- 基本语法 —— 快速了解Kotlin语法
- Idioms – learn how to write idiomatic Kotlin code for popular cases.
- 编码习惯 —— 学习常用的Kotlin编码习惯
- Java to Kotlin migration guide: Strings – learn how to perform typical tasks with strings in Java and Kotlin.
- Java 到 Kotlin 迁移指南:字符串 —— 了解如何在 Java 和 Kotlin 中使用字符串执行典型任务。
- Kotlin Koans – complete exercises to learn the Kotlin syntax. Each exercise is created as a failing unit test and your job is to make it pass.
- Kotlin Koans —— 学习 Kotlin 语法的完整练习。每个练习都是作为失败的单元测试创建的,你的工作就是让它通过。
- Kotlin by example – review a set of small and simple annotated examples for the Kotlin syntax.
- Kotlin 示例 —— 查看一组小而简单的 Kotlin 语法注释示例。
- Kotlin Basics track – learn all the Kotlin essentials while creating working applications step by step on JetBrains Academy.
- Kotlin Basics track – 在 JetBrains Academy 上逐步创建工作应用程序的同时学习所有 Kotlin 基础知识。
- Advent of Code puzzles – learn idiomatic Kotlin and practice your language skills by completing short and fun tasks.
- Advent of Code 谜题 - 学习惯用的 Kotlin 并通过完成简短而有趣的任务来练习您的语言技能。
- Kotlin books – find books we’ve reviewed and recommend for learning Kotlin.
- Kotlin 书籍 - 查找我们为学习 Kotlin 所审查和推荐的书籍。
- Kotlin hands-on tutorials – complete long-form tutorials to fully grasp a technology. These tutorials guide you through a self-contained project related to a specific topic.
- Kotlin 动手教程——完整的长篇教程以完全掌握一项技术。这些教程指导您完成与特定主题相关的独立项目。
- Kotlin for Java Developers – course for developers with experience in Java. It shows the similarities between the two languages and focuses on what’s going to be different.
- Kotlin for Java Developers – 面向具有 Java 经验的开发人员的课程。它显示了两种语言之间的相似之处,并着重于不同之处。
- Kotlin documentation in the PDF format – read the whole documentation offline.
- PDF 格式的 Kotlin 文档 – 离线阅读整个文档。
Basic syntax
基本语法
This is a collection of basic syntax elements with examples. At the end of every section, you’ll find a link to a detailed description of the related topic.
这是带有示例的基本语法元素的集合。 在每个部分的末尾,您都会找到指向相关主题详细说明的链接。
You can also learn all the Kotlin essentials with the free Kotlin Basics track on JetBrains Academy.
您还可以通过 JetBrains Academy 上的免费 Kotlin Basics 轨道学习所有 Kotlin 基础知识。
Package definition and imports
包定义和导入
Package specification should be at the top of the source file.
包定义应该在源文件的顶部。
package my.demo
import kotlin.text.*
// ...
It is not required to match directories and packages: source files can be placed arbitrarily in the file system.
不需要匹配目录和包:源文件可以任意放置在文件系统中。
See Packages.
Program entry point
程序进入点
An entry point of a Kotlin application is the main function.
Kotlin 应用程序的入口点是 main 函数。
fun main() {
println("Hello world!")
}
Another form of main accepts a variable number of String arguments.
main 的另一种形式接受可变数量的 String 参数。
fun main(args: Array<String>) {
println(args.contentToString())
}
Print to the standard output
打印到标准输出
print prints its argument to the standard output.
print 将其参数打印到标准输出。
fun main() {
print("Hello ")
print("world!")
}
println prints its arguments and adds a line break, so that the next thing you print appears on the next line.
println 打印它的参数并添加一个换行符,以便您打印的下一个内容出现在下一行。
fun main() {
println("Hello world!")
println(42)
}
Functions
函数
A function with two Int parameters and Int return type.
具有两个 Int 参数和 Int 返回类型的函数。
fun sum(a: Int, b: Int): Int {
return a + b
}
fun main() {
print("sum of 3 and 5 is ")
println(sum(3, 5))
}
A function body can be an expression. Its return type is inferred.
函数体可以是表达式,它会自动推断返回类型。
fun sum(a: Int, b: Int) = a + b
fun main() {
println("sum of 19 an 23 is ${sum(19, 23)}")
}
A function that returns no meaningful value.
一个返回无意义值的函数。
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
fun main() {
printSum(-1, 8)
}
Unit return type can be omitted.
Unit 返回类型可以省略。
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
fun main() {
printSum(-1, 8)
}
See Functions.
Variables
变量
Read-only local variables are defined using the keyword val. They can be assigned a value only once.
只读局部变量使用关键字 val 定义,它们只能被赋值一次。
fun main() {
val a: Int = 1 // immediate assignment
val b = 2 // `Int` type is inferred
val c: Int // Type required when no initializer is provided
c = 3 // deferred assignment
println("a = $a, b = $b, c = $c")
}
Variables that can be reassigned use the var keyword.
可以重新赋值的变量使用 var 关键字。
fun main() {
var x = 5
x += 1
println("x = $x")
}
You can declare variables at the top level.
您可以在顶层声明变量。
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
fun main() {
println("x = $x; PI = $PI")
incrementX()
println("incrementX()")
println("x = $x; PI = $PI")
}
See also Properties.
Creating classes and instances
创建类和实例
To define a class, use the class keyword.
要定义一个类,请使用 class 关键字。
class Shape
Properties of a class can be listed in its declaration or body.
类的属性可以在其声明或主体中列出。
class Rectangle(var height: Double, var length: Double) {
var perimeter = (height + length) * 2
}
The default constructor with parameters listed in the class declaration is available automatically.
含类声明且带参数的默认构造函数将自动可用。
class Rectangle(var height: Double, var length: Double) {
var perimeter = (height + length) * 2
}
fun main() {
var rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")
}
Inheritance between classes is declared by a colon (:). Classes are final by default; to make a class inheritable, mark it as open.
类之间的继承由冒号 (:) 声明。 默认情况下,类是最终的; 要使类可继承,请将其标记为 open 。
open class Shape
class Rectangle(var height: Double, var length: Double): Shape() {
var perimeter = (height + length) * 2
}
See classes and objects and instances.
Comments
注释
Just like most modern languages, Kotlin supports single-line (or end-of-line) and multi-line (block) comments.
就像大多数现代语言一样,Kotlin 支持单行(或行尾)和多行(块)注释。
// This is an end-of-line comment
/* This is a block comment
on multiple lines. */
Block comments in Kotlin can be nested.
Kotlin 中的块注释可以嵌套。
/* The comment starts here
/* contains a nested comment */
and ends here. */
See Documenting Kotlin Code for information on the documentation comment syntax.
有关文档注释语法的信息,请参阅 Documenting Kotlin Code 。
String templates
字符串模板
fun main() {
var a = 1
// simple name in template:
val s1 = "a is $a"
a = 2
// arbitrary expression in template:
val s2 = "${s1.replace("is", "was")}, but now is $a"
println(s2)
}
See String templates for details.
Conditional expressions
条件表达式
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
fun main() {
prinln("max of 0 and 42 is ${maxOf(0, 42)}")
}
In Kotlin, if can also be used as an expression.
在 Kotlin 中,if 也可以用作表达式。
fun maxOf(a: Int, b: Int) = if (a > b) a else b
fun main() {
prinln("max of 0 and 42 is ${maxOf(0, 42)}")
}
See if-expressions.
for loop
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
}
or
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
}
See for loop.
while loop
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
}
See while loop.
when expression
fun describe(obj: Any) String =
when(obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
fun main() {
println(describe(1))
println(describe("Hello"))
println(describe("1000L"))
println(describe(2))
println(describe("other"))
}
See when expression.
Ranges
范围
Check if a number is within a range using in operator.
使用 in 运算符检查数字是否在范围内。
fun main() {
val x = 10
val y = 9
if (x in 1..y+1) {
println("fits in range")
}
}
Check if a number is out of range.
检查数字是否超出范围。
fun main() {
val list = listOf("a", "b", "c")
if (-1 !in 0..list.lastIndex) {
println("-1 is out of range")
}
if (list.size !in list.indices) {
println("list size is out of valid list indices range, too")
}
}
Iterate over a range.
迭代一个范围
fun main() {
for (x in 1..5) {
print(x)
}
}
Or over a progression.
或者跳过一个处理元素
fun main() {
for (x in 1..10 step 2) {
print(x)
}
println()
for (x in 9 downTo 0 step 3) {
print(x)
}
}
Collections
Iterate over a collection.
迭代一个集合
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
}
Check if a collection contains an object using in operator.
使用 in 运算符检查集合是否包含一个对象。
fun main() {
val items = setOf("apple", "banana", "kiwifruit")
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}
}
Using lambda expressions to filter and map collections:
使用 lambda 表达式过滤和映射集合:
fun main() {
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.uppercase() }
.forEach { println(it) }
}
See Collections overview.
Nullable values and null checks
可空值和空检查
A reference must be explicitly marked as nullable when null value is possible. Nullable type names have ? at the end.
当变量值可能为 null 时,必须将其标记为可空类型。 可空类型 ? 在末尾。
Return null if str does not hold an integer:
如果 str 不包含整数,则返回 null:
fun parseInt(str : String): Int? {
// ...
}
Use a function returning nullable value:
使用返回可为空值的函数:
fun parseInt(str : String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// Using `x * y` yields error because they may hold nulls.
if (x != null && y != null) {
// x and y are automatically cast to non-nullable after null check
println(x * y)
} else {
println("'$arg1' or '$arg2' is not a number")
}
}
fun main() {
printProduct("6", "7")
printProduct("a", "7")
printProduct("a", "b")
}
or
fun parseInt(str : String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
if (x == null) {
println("Wrong number format in arg1: '$arg1'")
return
}
if (y == null) {
println("Wrong number format in arg2: '$arg2'")
return
}
// x and y are automatically cast to non-nullable after null check
println(x * y)
}
fun main() {
printProduct("6", "7")
printProduct("a", "7")
printProduct("a", "b")
}
See Null-safety.
Type checks and automatic casts
类型检查和自动转换
The is operator checks if an expression is an instance of a type. If an immutable local variable or property is checked for a specific type, there’s no need to cast it explicitly:
is 运算符检查表达式是否为类型的实例。如果为特定类型检查了不可变的局部变量或属性,则无需显式强制转换它:
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj` is automatically cast to `String` in this branch
return obj.length
}
// `obj` is still of type `Any` outside of the type-checked branch
return null
}
fun main() {
fun printLength(obj: Any) {
println("Getting the legnth of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a String"}")
}
printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
}
or
fun getStringLength(obj: Any): Int? {
if (obj !is String) return null
// `obj` is automatically cast to `String` in this branch
return obj.length
}
fun main() {
fun printLength(obj: Any) {
println("Getting the legnth of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a String"}")
}
printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
}
or even
fun getStringLength(obj: Any): Int? {
// `obj` is automatically cast to `String` on the rigth-hand side of `&&`
if (obj is String && obj.length > 0) {
return obj.length
}
return null
}
fun main() {
fun printLength(obj: Any) {
println("Getting the legnth of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a String"}")
}
printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
}
See Classes and Type casts.
Idioms
A collection of random and frequently used idioms in Kotlin. If you have a favorite idiom, contribute it by sending a pull request.
Kotlin 中随机且常用的idioms集合。 如果您有最喜欢的编码习惯,请通过发送拉取请求来贡献它。


