与Java不同的是,Kotlin只需要创建一个.kt的文件即可运行,无需创建类。
程序起点 main函数
简单版的main函数,.kt文件,写一个main()函数,即可运行
fun main() {println("Hello world!")}
有入参的mian函数,负责接收环境变量等参数
fun main(args: Array<String>) {println(args.contentToString())}
包定义和导入包
它不需要匹配目录和包:源文件可以任意放置在文件系统中。
package my.demoimport kotlin.text.*// ...
打印标准输出
// 普通输出print("Hello ")print("world!")// 输出并换行println("Hello world!")
常量和变量
//常量 valval a: Int = 1 // immediate assignmentval b = 2 // `Int` type is inferredval c: Int // Type required when no initializer is providedc = 3 // deferred assignment//变量 varvar x = 5 // `Int` type is inferredx += 1
函数
//具有两个参数和返回类型的函数。//变量类型紧随其后用冒号隔开 符号人类习惯,先想变量名称在想类型fun sum(a: Int, b: Int): Int {return a + b}//函数主体可以是一种表达。推断其返回类型。可以省略花括号fun sum(a: Int, b: Int) = a + b//不返回任何有意义的值的函数。fun printSum(a: Int, b: Int): Unit {println("sum of $a and $b is ${a + b}")}//Unit可以省略返回类型。fun printSum(a: Int, b: Int) {println("sum of $a and $b is ${a + b}")}//默认参数fun read(b: ByteArray,off: Int = 0,len: Int = b.size,//如果默认参数后的最后一个参数是lambda,则可以将其作为指定参数或括号外传递:qux: () -> Unit,) { /*...*/ }//泛型函数fun <T> singletonList(item: T): List<T> { /*...*/ }
无修复符号
使用无定形符号标记的功能也可以称为使用无缀符号(省略呼叫的点和括号)。修复功能必须满足以下要求:infix
- 它们必须是成员功能或扩展功能。
- 它们必须具有单个参数。
- 参数不得接受可变参数数,并且不得具有默认值。
infix fun Int.shl(x: Int): Int { ... }// calling the function using the infix notation1 shl 2// is the same as1.shl(2)
与算术操作员、类型转换和操作员相比,Infix 函数呼叫的优先级较低。以下表示等效:
rangeTo1 shl 2 + 3相当于1 shl (2 + 3)0 until n * 2相当于0 until (n * 2)xs union ys as Set<*>相当于xs union (ys as Set<*>)
另一方面,修复功能呼叫的优先级高于胸部操作员和 -和检查,以及其他一些操作员的优先级。这些表达式也等同于:
&&``||``is``ina && b xor c相当于a && (b xor c)a xor b in c相当于(a xor b) in c
请注意,修复功能始终需要指定接收器和参数。当您使用无定形符号在当前接收器上调用方法时,请明确使用。这需要确保明确解析。this
class MyStringCollection {infix fun add(s: String) { /*...*/ }fun build() {this add "abc" // Correctadd("abc") // Correct//add "abc" // Incorrect: the receiver must be specified}}
尾部递归功能
科特林支持一种称为尾部递归的功能编程风格。对于通常使用循环的某些算法,您可以使用递归函数,而不会出现堆栈溢出的风险。当一个函数标记为修饰符并满足所需的正式条件时,编译器会优化递归,留下一个快速高效的基于循环的版本:tailrec
val eps = 1E-10 // "good enough", could be 10^-15tailrec fun findFixPoint(x: Double = 1.0): Double =if (Math.abs(x - Math.cos(x)) < eps) x else findFixPoint(Math.cos(x))
此代码计算宇宙,这是一个数学常数。它只是反复调用,直到结果不再改变,产生指定精度的结果。生成的代码相当于这种更传统的样式:fixpoint``Math.cos``1.0``0.7390851332151611``eps
val eps = 1E-10 // "good enough", could be 10^-15private fun findFixPoint(): Double {var x = 1.0while (true) {val y = Math.cos(x)if (Math.abs(x - y) < eps) return xx = Math.cos(x)}}
要符合修改器的资格,函数必须称为其执行的最后一个操作。当递归调用后有更多的代码时,您不能使用尾部递归,并且您不能在//块内使用它。目前,尾部递归由科特林为合资企业和科特林/本地支持。tailrec``try``catch``finally
类和对象
//定义类class Shape//定义有属性的类class Rectangle(var height: Double, var length: Double) {var perimeter = (height + length) * 2}val rectangle = Rectangle(5.0, 2.0)println("The perimeter is ${rectangle.perimeter}")//允许类继承 添加关键字openopen class Shapeclass Rectangle(var height: Double, var length: Double): Shape() {var perimeter = (height + length) * 2}
注释
//单行注释/*多行注释*/
字符串
var a = 1//字符串模板 $可以直接取变量值val s1 = "a is $a"a = 2// ${}可以在字符串模板中进行计算和调用val s2 = "${s1.replace("is", "was")}, but now is $a"
条件表达式 if else
fun maxOf(a: Int, b: Int): Int {if (a > b) {return a} else {return b}}等同于fun maxOf(a: Int, b: Int) = if (a > b) a else b
循环 for
val items = listOf("apple", "banana", "kiwifruit")for (item in items) {println(item)}或者val items = listOf("apple", "banana", "kiwifruit")for (index in items.indices) {println("item at $index is ${items[index]}")}
循环 while
val items = listOf("apple", "banana", "kiwifruit")var index = 0while (index < items.size) {println("item at $index is ${items[index]}")index++}
当 when
//类似java的case语句,但更简单fun describe(obj: Any): String =when (obj) {1 -> "One""Hello" -> "Greeting"is Long -> "Long"!is String -> "Not a string"else -> "Unknown"}
范围 ..
//输出从1到5for (x in 1..5) {print(x)}//x是否在1-y+1之间val x = 10val y = 9if (x in 1..y+1) {println("fits in range")}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")}//指定步长for (x in 1..10 step 2) {print(x)}println()for (x in 9 downTo 0 step 3) {print(x)}
存在 in
for (item in items) {println(item)}when {"orange" in items -> println("juicy")"apple" in items -> println("apple is fine too")}val fruits = listOf("banana", "avocado", "apple", "kiwifruit")fruits.filter { it.startsWith("a") }.sortedBy { it }.map { it.uppercase() }.forEach { println(it) }
空指针问题解决 ?!
//定义变量var helloB : String?//为空返回null ?helloB?.length//为空抛异常helloB!.length
