Kotlin 示例

2021-03-08  本文已影响0人  candice2cc

介绍

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
}
  1. 简单的函数,参数为String类型,返回Unit类型(无返回值)。
  2. 第二个参数设置默认值,返回类型缺省,意味着实际返回类型为Unit
  3. 返回Int类型
  4. 单表达式函数,返回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安全

为了避免NullPointerExceptionkotlin语言不允许变量赋值为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提供所有公共循环:forwhiledo-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
  1. 在class中定义iterator,必须命名为iterator,并且有operator修饰符
  2. 返回的iterator必须满足以下的方法:
    • next():Animal
    • hasNext():Boolean
  3. 循环自定义的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

Lambda函数

上一篇 下一篇

猜你喜欢

热点阅读