介绍
Hello World
package org.kotlinlang.play // 1
fun main() { // 2
println("Hello, World!") // 3
}
kotlin应用的入口是main
方法。
函数
fun printMessage(message: String): Unit { // 1
println(message)
}
fun printMessageWithPrefix(message: String, prefix: String = "Info") { // 2
println("[$prefix] $message")
}
fun sum(x: Int, y: Int): Int { // 3
return x + y
}
fun multiply(x: Int, y: Int) = x * y // 4
fun main() {
printMessage("Hello") // 5
printMessageWithPrefix("Hello", "Log") // 6
printMessageWithPrefix("Hello") // 7
printMessageWithPrefix(prefix = "Log", message = "Hello") // 8
println(sum(1, 2)) // 9
println(multiply(2, 4)) // 10
}
- 简单的函数,参数为
String
类型,返回Unit
类型(无返回值)。 - 第二个参数设置默认值,返回类型缺省,意味着实际返回类型为
Unit
。 - 返回
Int
类型 - 单表达式函数,返回
Int
类型
Infix 函数
fun main() {
infix fun Int.times(str: String) = str.repeat(this) // 1
println(2 times "Bye ") // 2
val pair = "Ferrari" to "Katrina" // 3
println(pair)
infix fun String.onto(other: String) = Pair(this, other) // 4
val myPair = "McLaren" onto "Lucas"
println(myPair)
val sophia = Person("Sophia")
val claudia = Person("Claudia")
sophia likes claudia // 5
}
class Person(val name: String) {
val likedPeople = mutableListOf<Person>()
infix fun likes(other: Person) { likedPeople.add(other) } // 6
}
输出
Bye Bye
(Ferrari, Katrina)
(McLaren, Lucas)
Operator函数
operator fun Int.times(str: String) = str.repeat(this) // 1
println(2 * "Bye ") // 2
operator fun String.get(range: IntRange) = substring(range) // 3
val str = "Always forgive your enemies; nothing annoys them so much."
println(str[0..14])
输出
Bye Bye
Always forgive
varargs 函数参数
fun printAll(vararg messages: String) { // 1
for (m in messages) println(m)
}
printAll("Hello", "Hallo", "Salut", "Hola", "你好") // 2
fun printAllWithPrefix(vararg messages: String, prefix: String) { // 3
for (m in messages) println(prefix + m)
}
printAllWithPrefix(
"Hello", "Hallo", "Salut", "Hola", "你好",
prefix = "Greeting: " // 4
)
fun log(vararg entries: String) {
printAll(*entries) // 5
}
输出
Hello
Hallo
Salut
Hola
你好
Greeting: Hello
Greeting: Hallo
Greeting: Salut
Greeting: Hola
Greeting: 你好
变量
var a: String = "initial" // 1
println(a)
val b: Int = 1 // 2
val c = 3 // 3
输出
initial
定义变量,不初始化
var e: Int // 1
println(e) // 2
输出
Variable 'e' must be initialized
你可以自由选择初始化变量的时机。但是,第一次读取变量时必须先进行初始化。
val d: Int // 1
if (someCondition()) {
d = 1 // 2
} else {
d = 2 // 2
}
println(d) // 3
Null安全
为了避免NullPointerException
,kotlin
语言不允许变量赋值为null
。如果你需要一个可为null
的变量,声明它的时候需要在类型的末尾增加?
var neverNull: String = "This can't be null" // 1
neverNull = null // 2
var nullable: String? = "You can keep a null here" // 3
nullable = null // 4
var inferredNonNull = "The compiler assumes non-null" // 5
inferredNonNull = null // 6
fun strLength(notNull: String): Int { // 7
return notNull.length
}
strLength(neverNull) // 8
strLength(nullable) // 9
输出
2- Null can not be a value of a non-null type String
6- Null can not be a value of a non-null type String
9- Type mismatch: inferred type is Nothing? but String was expected
使用Nulls
有些时候,Kotlin
程序需要使用null
,例如:与Java代码交互、代表一个为空的状态。
Kotlin
提供一个null跟踪机制,可以优雅地处理这些场景。
fun describeString(maybeString: String?): String { // 1
if (maybeString != null && maybeString.length > 0) { // 2
return "String of length ${maybeString.length}"
} else {
return "Empty or null string" // 3
}
}
Classes
class Customer // 1
class Contact(val id: Int, var email: String) // 2
fun main() {
val customer = Customer() // 3
val contact = Contact(1, "mary@gmail.com") // 4
println(contact.id) // 5
contact.email = "jane@gmail.com" // 6
}
输出
1
泛型
泛型Class
class MutableStack<E>(vararg items: E) { // 1
private val elements = items.toMutableList()
fun push(element: E) = elements.add(element) // 2
fun peek(): E = elements.last() // 3
fun pop(): E = elements.removeAt(elements.size - 1)
fun isEmpty() = elements.isEmpty()
fun size() = elements.size
override fun toString() = "MutableStack(${elements.joinToString()})"
}
输出
MutableStack(0.62, 3.14, 2.7, 9.87)
peek(): 9.87
MutableStack(0.62, 3.14, 2.7, 9.87)
pop(): 9.87
MutableStack(0.62, 3.14, 2.7)
pop(): 2.7
MutableStack(0.62, 3.14)
pop(): 3.14
MutableStack(0.62)
pop(): 0.62
MutableStack()
泛型函数
fun <E> mutableStackOf(vararg elements: E) = MutableStack(*elements)
fun main() {
val stack = mutableStackOf(0.62, 3.14, 2.7)
println(stack)
}
输出
MutableStack(0.62, 3.14, 2.7)
继承
open class Dog { // 1
open fun sayHello() { // 2
println("wow wow!")
}
}
class Yorkshire : Dog() { // 3
override fun sayHello() { // 4
println("wif wif!")
}
}
fun main() {
val dog: Dog = Yorkshire()
dog.sayHello()
}
有参构造函数
open class Tiger(val origin: String) {
fun sayHello() {
println("A tiger from $origin says: grrhhh!")
}
}
class SiberianTiger : Tiger("Siberia") // 1
fun main() {
val tiger: Tiger = SiberianTiger()
tiger.sayHello()
}
输出
A tiger from Siberia says: grrhhh!
传递构造函数参数给父类
open class Lion(val name: String, val origin: String) {
fun sayHello() {
println("$name, the lion from $origin says: graoh!")
}
}
class Asiatic(name: String) : Lion(name = name, origin = "India") // 1
fun main() {
val lion: Lion = Asiatic("Rufo") // 2
lion.sayHello()
}
输出
Rufo, the lion from India says: graoh!
控制流
When
kotlin
提供更灵活简洁的when
。
fun main() {
cases("Hello")
cases(1)
cases(0L)
cases(MyClass())
cases("hello")
}
fun cases(obj: Any) {
when (obj) { // 1
1 -> println("One") // 2
"Hello" -> println("Greeting") // 3
is Long -> println("Long") // 4
!is String -> println("Not a string") // 5
else -> println("Unknown") // 6
}
}
class MyClass
输出
Greeting
One
Long
Not a string
Unknown
所有的条件分支流程按序检查,直到满足一个条件为止。因此,只有第一个满足条件的分支被执行。
When表达式
fun main() {
println(whenAssign("Hello"))
println(whenAssign(3.4))
println(whenAssign(1))
println(whenAssign(MyClass()))
}
fun whenAssign(obj: Any): Any {
val result = when (obj) { // 1
1 -> "one" // 2
"Hello" -> 1 // 3
is Long -> false // 4
else -> 42 // 5
}
return result
}
class MyClass
输出
1
42
one
42
Loops
kotlin
提供所有公共循环:for
,while
,do-while
for
val cakes = listOf("carrot", "cheese", "chocolate")
for (cake in cakes) { // 1
println("Yummy, it's a $cake cake!")
}
while 和 do-while
fun eatACake() = println("Eat a Cake")
fun bakeACake() = println("Bake a Cake")
fun main(args: Array<String>) {
var cakesEaten = 0
var cakesBaked = 0
while (cakesEaten < 5) { // 1
eatACake()
cakesEaten ++
}
do { // 2
bakeACake()
cakesBaked++
} while (cakesBaked < cakesEaten)
}
Iterators
通过iterator
操作符,可以自定义Iterators。
class Animal(val name: String)
class Zoo(val animals: List<Animal>) {
operator fun iterator(): Iterator<Animal> { // 1
return animals.iterator() // 2
}
}
fun main() {
val zoo = Zoo(listOf(Animal("zebra"), Animal("lion")))
for (animal in zoo) { // 3
println("Watch out, it's a ${animal.name}")
}
}
输出
Watch out, it's a zebra
Watch out, it's a lion
- 在class中定义
iterator
,必须命名为iterator
,并且有operator
修饰符 - 返回的
iterator
必须满足以下的方法:- next():Animal
- hasNext():Boolean
- 循环自定义的
iterator
Ranges
fun main() {
for(i in 0..3) { // 1
print(i)
}
print(" ")
for(i in 0 until 3) { // 2
print(i)
}
print(" ")
for(i in 2..8 step 2) { // 3
print(i)
}
print(" ")
for (i in 3 downTo 0) { // 4
print(i)
}
print(" ")
}
输出
0123 012 2468 3210
range也可以用在if
条件语句。
val x = 2
if (x in 1..5) { // 1
print("x is in range from 1 to 5")
}
println()
if (x !in 6..10) { // 2
print("x is not in range from 6 to 10")
}
输出
x is in range from 1 to 5
x is not in range from 6 to 10
相等判断
==
与===
val authors = setOf("Shakespeare", "Hemingway", "Twain")
val writers = setOf("Twain", "Shakespeare", "Hemingway")
println(authors == writers) // 1
println(authors === writers) // 2
条件表达式
kotlin里没有三元表达式,使用if可以替代相同的效果
fun max(a: Int, b: Int) = if (a > b) a else b // 1
println(max(99, -42))
输出
99
特定的类
Data类
Data类很方便被用来存储数据。
data class User(val name: String, val id: Int) // 1
fun main() {
val user = User("Alex", 1)
println(user) // 2
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)
println("user == secondUser: ${user == secondUser}") // 3
println("user == thirdUser: ${user == thirdUser}")
println(user.hashCode()) // 4
println(secondUser.hashCode())
// copy() function
println(user.copy()) // 5
println(user.copy("Max")) // 6
println(user.copy(id = 2)) // 7
println("name = ${user.component1()}") // 8
println("id = ${user.component2()}")
}
输出
User(name=Alex, id=1)
user == secondUser: true
user == thirdUser: false
63347075
63347075
User(name=Alex, id=1)
User(name=Max, id=1)
User(name=Alex, id=2)
name = Alex
id = 1
Enum类
Enum类用来枚举有限的一组值。
enum class State {
IDLE, RUNNING, FINISHED // 1
}
fun main() {
val state = State.RUNNING // 2
val message = when (state) { // 3
State.IDLE -> "It's idle"
State.RUNNING -> "It's running"
State.FINISHED -> "It's finished"
}
println(message)
}
输出
It's running
enum class Color(val rgb: Int) { // 1
RED(0xFF0000), // 2
GREEN(0x00FF00),
BLUE(0x0000FF),
YELLOW(0xFFFF00);
fun containsRed() = (this.rgb and 0xFF0000 != 0) // 3
}
fun main() {
val red = Color.RED
println(red) // 4
println(red.containsRed()) // 5
println(Color.BLUE.containsRed()) // 6
}
输出
RED
true
false
Sealed(密封) 类
Sealed类限制了继承。它只允许被同一个文件内的类继承。
sealed class Mammal(val name: String) // 1
class Cat(val catName: String) : Mammal(catName) // 2
class Human(val humanName: String, val job: String) : Mammal(humanName)
fun greetMammal(mammal: Mammal): String {
when (mammal) { // 3
is Human -> return "Hello ${mammal.name}; You're working as a ${mammal.job}" // 4
is Cat -> return "Hello ${mammal.name}" // 5
} // 6
}
fun main() {
println(greetMammal(Cat("Snowy")))
}
输出
Hello Snowy
对象关键字
在Java中,经常使用单例模式。
在Kotlin中,你只需要定义一个object:没有class,没有构造函数,是一个lazy对象。为啥是lazy呢?因为它只在对象访问的时候才被创建,而且只创建一次。
object表达式
下面是一种典型的使用场景,类似于Java的匿名类实例。
fun rentPrice(standardDays: Int, festivityDays: Int, specialDays: Int): Unit { //1
val dayRates = object { //2
var standard: Int = 30 * standardDays
var festivity: Int = 50 * festivityDays
var special: Int = 100 * specialDays
}
val total = dayRates.standard + dayRates.festivity + dayRates.special //3
print("Total price: $$total") //4
}
fun main() {
rentPrice(10, 2, 1) //5
}
输出
Total price: $500
object 定义
object定义不是一个表达式,也不能被用来进行变量赋值。你可以直接访问它的成员。
object DoAuth { //1
fun takeParams(username: String, password: String) { //2
println("input Auth parameters = $username:$password")
}
}
fun main(){
DoAuth.takeParams("foo", "qwerty") //3
}
输出
input Auth parameters = foo:qwerty
Companion Object
类似于Java中的静态方法。
class BigBen { //1
companion object Bonger { //2
fun getBongs(nTimes: Int) { //3
for (i in 1 .. nTimes) {
print("BONG ")
}
}
}
}
fun main() {
BigBen.getBongs(12) //4
}
输出
BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG
函数式
高阶函数
高阶函数:将其他函数作为参数或者作为返回值的函数。
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int { // 1
return operation(x, y) // 2
}
fun sum(x: Int, y: Int) = x + y // 3
fun main() {
val sumResult = calculate(4, 5, ::sum) // 4
val mulResult = calculate(4, 5) { a, b -> a * b } // 5
println("sumResult $sumResult, mulResult $mulResult")
}
输出
sumResult 9, mulResult 20
返回函数
fun operation(): (Int) -> Int { // 1
return ::square
}
fun square(x: Int) = x * x // 2
fun main() {
val func = operation() // 3
println(func(2)) // 4
}
输出
4
网友评论