Kotlin self-freestyle

版权声明:本文为博博原创文章,未经博博允许不得转载。 https://blog.csdn.net/u013523377/article/details/72617847

package com.my.application

import com.my.view
import com.my.ui

普通类

class Test{}

构造器

  • 主级构造器
class Test constructor(ctx: Context){

}
  • 多级构造器
class Test {

    constructor(ctx: Context) {

    }

    constructor (ctx: Context, title: String) {

    }
}
  • 代理主级构造器
class Test constructor(ctx: Context) {

    constructor (ctx: Context, title: String) : this(ctx) {

    }
}
  • 封闭式构造器
class Test private constructor() {

}

说白了就是不给外部实例化该对象

  • 构造器初始操作
class Test constructor(ctx: Context){

    var mContext : Context? = null 

    init{
        mContext = ctx
    }
}
  • 直接赋值操作
class Test constructor(var mContext: Context){

}
  • 默认值操作
class Test constructor(userInfo : UserInfo = UserInfo()) {

}

调用时若无传参,即相当于无参构造函数

继承

  • 无主级构造器
open class Base {

    constructor(ctx: Context)
}


class Test1 : Base {

    constructor(ctx: Context) : super(ctx)
}

class Test2(ctx: Context) : TestBase(ctx)
  • 携主级构造器
open class Base (ctx: Context)


class Test(ctx: Context) : Base (ctx)
  • 方法的重写
open class Base {
    open fun output(){}
}


class Test1 : Base {

    override fun output() {
        super.output()
    }
}

class Test2 : Base {

    // 加上 final 修饰符表示该方法不被重写
    final override fun output() {
        super.output()
    }
}
  • 属性的重写
open class Base {

    open val mTitle: String? = null
    open var mContent: String? = null
}


class Test1 : Base {

    override val mTitle: String?
        get() = super.mTitle

    override var mContent: String?
        get() = super.mContent
        set(value) {}
}

class Test2 : Base {

    // 更换属性类型为可变,反之不行
    override var mTitle: String
        get() = super.mTitle
        set(value) {title = value}

    // 修改属性为抽象
    override abstract var mContent: String?
}

class Test3(override var x: Int) : Base {

}

接口

open class TestBase {

    open fun output() {}
}

interface TestInterface {

    fun output() {}
}

class TestKotlin : TestBase(), TestInterface {

    override fun output() {
        super<TestBase>.output()
        super<TestInterface>.output()
    }
}

密封类

package com.urun.ulk

fun main(str: Array<String>) {
    test(TestBase.Test1())
    test(TestBase.Test2)
}

fun test(instance: TestBase) = when (instance) {
    is TestBase.Test1 -> instance.output()
    is TestBase.Test2 -> instance.output()
}

sealed class TestBase {

    open fun output() {

    }

    class Test1 : TestBase() {
        override fun output() {
            print("Kotlin")
        }
    }

    object Test2 : TestBase() {
        override fun output() {
            print("异端纪要")
        }
    }
}

关键字-sealed,每个密封类只有一个实例,密封类的子类可以有包含不同状态的多个实例。如果 sealed

数据类

data class UserInfo(val name: String, val age: Int){}

1.data 作为数据类的修饰符
2.主构造函数应该至少有一个参数,且所有参数必须标注为 val 或者 var
3.数据类不能是 abstract,open,sealed,或者 inner。不能继承其它的类(但可以实现接口)
4.在 JVM 中如果构造函数是无参的,则所有的属性必须有默认的值

// 类复制(仅修改部分数据实现新对象的创建)
val jack = UserInfo(name = "jack", age = 18)
val jome = jack.copy(name = "jome")

// data 特性,输出 "UserInfo(name=jome, age=18)"
print(jome.toString())

// 多重声明
val (name, age) = jome
// 输出 "jome, 18 years of age"
println("$name, $age years of age")

嵌套类

fun main(args: Array<String>) {

    // 匿名内部类
    val rnb = Runnable{
        run {
            print(UserInfo().mName)
            print(UserInfo.Father().mName())
            print(UserInfo().Mother().mName())
        }
    }
}

class UserInfo {

    var mName = "child"

    // 嵌套类
    class Father {
        fun mName() = "Java"
    }

    // 内部类
    inner class Mother {
        fun mName() = "Kotlin"
    }
}

枚举类

enum class Star(val hasWater: Boolean? = false) {
    Mars,
    EARTH(true) 
}

每个枚举都是枚举类的一个实例,可初始

fun main(args: Array<String>) {

    // Star.valueOf(value: String): Star 根据枚举名字进行匹配,匹配不到抛异常
    // Star.values(): Array<Star> 获取所有枚举常量

    for (it in Star.values()) {
        println("no.${it.ordinal} i am ${it.name} , ${it.introduce()}")
    }

    // 输出:
    // no.0 i am Mars , i have ufo
    // no.1 i am EARTH , i have Human
}

enum class Star {
    Mars {
        override fun introduce(): String {
            return "i have ufo"
        }
    },
    EARTH {
        override fun introduce(): String {
            return "i have Human"
        }
    };

    abstract fun introduce(): String
}

枚举定义了其他成员,需用分号 ; 把枚举常量定义和成员定义分开

类代理

interface Put {
    fun out()
}

class PutImpl(var str: String) : Put {
    override fun out() {
        print(str)
    }
}

// 将 p 存储在 OutPut 内部对象,且 p 持有 Put 的所有方法
class OutPut(p: Put) : Put by p {
    fun sayHello() = print("Hello!!")
}

fun main(args: Array<String>) {

    val p = PutImpl("Kotlin 异端纪要")
    OutPut(p).out()
    OutPut(p).sayHello()
}

代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装

泛型

class TestKotlin<T> (t: T){
    var value = t
}

泛型上界(上限)使用 out 符号进行修饰,表示类型为 T 或者 T 的子类。且 T 只能作为返回值而不能被消耗或被当成参数使用,这里 T 称为协变类型参数。如限定类型只能为 String 类或其子类:

abstract class Source<out T> {
    abstract fun nextT(): T
}

fun foo(strs: Source<String>) {
    val objects: Source<Any> = strs
}

泛型下界(下限)使用 in 符号进行修饰, 表示类型为 T 的超类。且 T 只能被用作方法的参数,被操作,而不能作为返回值使用,这里 T 称为逆变类型参数。如限定类型超类只能是 Int:

abstract class Comparable<in T> {
    abstract fun compareTo(other: T): Int
}

fun foo(x: Comparable<Number>) {
    x.compareTo(1.0) 
    val y: Comparable<Double> = x 
}

类型判断

if (obj is String) {}
if (obj !is String) {}

函数

普通函数

fun outPut(){
    println("Kotlin 异端纪要")
}

单表达式

fun print() = println("Kotlin 异端纪要")

仅当函数只返回单个表达式时才能使用。如果是带返回值的函数,返回值的类型可写可不写

携参

fun outPut(str: String){
    println(str)
}

返回值

一切 kotlin 函数都会返回一个值,若没有指定,默认返回一个 Unit 类

fun outPut(str: String): String {
    return "Kotlin 异端纪要返回:" + str
}
fun print(): Unit {
    println("Kotlin 异端纪要")
}

// 等同于(推荐写法)

fun print() {
    println("Kotlin 异端纪要")
}

return null 值避开空异常

默认返回值

fun outPut(str: String = "我是默认值"): String {
    return "Kotlin 异端纪要返回:" + str
}

备默认值减少重载,方便使用

变长参数

fun outPut(vararg str: String) {
    println("Kotlin 异端纪要返回:" + str)
}

outPut("Kotlin","异端","纪要")

(修饰符-vararg)入参可赋值,且可赋多值,也可不赋值。多参情况下一般至于最后一个位置,如果是其余位置则需依命名原则入参。

多参

fun outPut(str1: String, str2: String = "我是默认值"): String {
    return "Kotlin 异端纪要返回:" + str1 + str2
}

outPut("只传一个值")
outPut("传一个值", "再传一个值")
outPut(str1 = "传一个值", str2 = "再传一个值")

自备参数名增强代码可读性

扩展

// 属性扩展
val kotlin.String.lastIndex: Int
    get() = length - 1

print("Kotlin 异端纪要".lastIndex)

// 函数扩展
infix fun String.out(str : String): String {
    return "Kotlin 异端纪要扩展:" + str
}

"扩展函数使用" out "入参内容"// 用中缀福 infix 注解调用扩展函数
"扩展函数使用".out("入参内容")

1.初始化函数不持有扩展属性
2.实际上通过扩展得以调用新的函数,但并非修改原有的内部函数
3.原持有函数的优先级高于自定义扩展函数(即同名同参时仅调用原有函数)

局部

fun outPut(str : String) {
    var str = "Kotlin 异端纪要"
    fun out() {
        print(str)
        return
    }
}

可调用外部函数及其成员变量

泛型

fun <T> print(obj: T): T {
    return obj
}
// 泛型约束,单个上界
fun <T : Comparable<T>> print(obj: T): T {
    return obj
}
// 泛型约束,多个上界
fun <T> print(obj: T): T
        where T : Comparable<T>, T : Cloneable {
    return obj
}

高阶

fun getTitle() = "Kotlin 异端纪要"

fun input(body: () -> String): String {
    return body()
}

fun outPut() {
    print(input({ getTitle() }))
}

内联

解决程序中函数调用的效率问题,降低运行时内存的开销

fun getTitle() = "Kotlin"
fun getContent() = "异端纪要"

inline fun input(title: () -> String, noinline content: () -> String): String {
    return title() + content()
}

fun outPut() {
    print(input({ getTitle() }, { getContent() }))
}

多用

用 with 实现 Test实例对象中多个属性或者方法的调用

fun main(args: Array<String>) {

    with(Test()) {
        setTitle(mName)
        setContent("异端纪要")
    }
}

class Test {
    val mName = "Kotlin"
    fun setTitle(title: String){}
    fun setContent(content: String){}
}

空安全

属性

// title 可被赋空值
var title: String? = null

返回值

// 返回 null 结果,避免 NPE 抛出
fun getTitle(): String? {
    return null
}

空判断

val a: String? = null

// 允许 a 为空值,且空值输出 "Kotlin 异端纪要"
print(a?.length ?: "Kotlin 异端纪要")

// 不允许 a 为空值,空值抛出 NPE
print(a!!.length)

Elvis 操作符 [ ?: ], NPE-lovers 操作符 [ !! ]

空使用

val list: ArrayList<UserInfo>? = null

list?.let {
    // list 非空处理
    print(list[0].mName?.length ?: "mName 非空输出")
} ?: print("list 空输出")

【 ?. 】非空;【 ?.let 】 非空处理;【 ?: 】否则

类型

类型判断

val a: String? = null

// 如果 a 非 Int 类型,那么赋值为 null
val b: Int? = a as? Int

类型转变

// 生产不消费
abstract class Source<out T> {
    abstract fun nextT(): T
}

fun demo(strs: Source<String>) {
    val objects: Source<Any> = strs
    //...
}
// 消费不生产
abstract class Source<in T> {
    abstract fun nextT(other: T): String
}

fun demo(strs: Source<Char>) {
    strs.nextT('a')
    val objects: Source<Char> = strs
}

Java: 生产者 extens,消费者 super
Kotlin: 生产者 out,消费者 in

属性

可变属性,变量

var mName: String ?= null

只读属性

val mName: String ?= null

代理

Get-Set

class Delegate {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name} in $thisRef.'")
    }
}

class Example {
    var p: String by Delegate()
}

fun main(args: Array<String>) {
    val e = Example()
    println(e.p)// 输出:Example@5674cd4d, thank you for delegating 'p' to me!
    e.p = "NEW"// 输出:NEW has been assigned to 'p in Example@5674cd4d.'
}

thisRef 接收者–必须是属性拥有者是同一种类型,或者是其父类
property 必须是 KProperty<*> 或这它的父类

Lazy

// 单线程执行,多个线程使用,尽在一个线程完成初始工作
// val mName: String by lazy { getName() }
val mName: String by lazy(LazyThreadSafetyMode.NONE) { getName() }

// 多线程执行,多个线程使用,每个线程独自完成初始工作
// val mName: String by lazy(LazyThreadSafetyMode.PUBLICATION) { getName() }

fun getName(): String {
    println("init value")
    return "Kotlin"
}

fun main(args: Array<String>) {
    println(mName)
    println(mName)
}

// 输出:
// init value
// Kotlin
// Kotlin

初始工作仅发生在属性被第一使用时,以后每次调用只简单返回之前存储的值

Delegates

// prop-属性,old-旧值,new-新值
var mName: String by Delegates.observable("Java") {
    prop, old, new ->
    println("$old -> $new")
}

mName = "Kotlin"
mName = "Android"

log:
Java -> Kotlin
Kotlin -> Android

// vetoable() 实现赋值控制,仅在满足条件为true的情况下赋值
var mName: String by Delegates.vetoable("Java") {
    prop, old, new ->
    println("$old -> $new")
    new == "Spring"//if(new == "Sprint") true else false
}

mName = "Kotlin"
mName = "Spring"
mName = "Android"

log:
Java -> Kotlin
Java -> Spring
Spring -> Android

Map

class UserInfo(val map: Map<String, Any?>) {
    val mName: String by map
    val mAge: Int by map
}

fun main(args: Array<String>) {
    val user = UserInfo(mapOf(
            "mName" to "Kotlin",
            "mAge" to 25
    ))

    println(user.mName)// 输出:Kotlin
    println(user.mAge)// 输出:25
}

getter 与 setter

var mName
    get() = this.toString()
    set(value) {
        mName = value
    }

// 指定默认类型
var mNick = String
    get
    set(value) {
        mNick = value
    }

// 指定默认值
var mAge = 18
    set(value) {
        if (value > 0) mAge = value else mAge = 0
    }

单例

// 类
class Loader {
    companion object {
        fun create(): Loader = Loader()
        val mTitle = "Kotlin 异端纪要"
    }
}

fun test(){
    // 实例化 Loader (以下效果一致)
    // val mLoader = Loader.create()
    val mLoader = Loader.Companion

    print(mLoader.mTitle)
}

// 函数
private fun singleton() = object {
    val mTitle: String = "Kotlin 异端纪要"
}

fun test(){
    print(singleton().mTitle)
}

// 实体
object User{
    val mName = "Kotlin 异端纪要"
}

fun test(){
    print(User.mName)
}

静态声明

通过修饰符 companion object {} (伴随对象)实现静态内容的声明

companion object {
    val APP_NAME = "Kotlin_APP"
    val APP_NO = "20170707"
}

多重声明

class Info(val name :String, val age: Int){

    operator fun component1(): String {
        return name
    }

    operator fun component2(): Int {
        return age
    }
}

fun main(args: Array<String>) {

    val info = Info("Kotlin", 25)

    // 一次创建了多个变量
    var (name, age) = info

    // 基本编译实现
    // var name = info.component1()
    // var age = info.component2()

    print("name:$name,age:$age")//log:"name:Kotlin,age:25"
}

流程控制

ranges

val list = listOf("one", "two", "three")
val map = mapOf("one" to 1, "two" to 2, "three" to 3)
val number = 5
val value = "none"

// 数值范围比较(以下效果一致,其中 until 表示不包括 list.size,所以 +1)
if (number until 0..(list.size + 1)) {}
if (number in 0..list.size) {}
if (number in 0..list.lastIndex) {}
if (number in list.indices) {}

// 字符串范围比较(真心没搞懂)
if (value !in "a".."b"){}

// 集合迭代(以下效果一致)
for (str in list) {}
for (str: String in list) {}

// 递增进步迭代(以下效果一致)
for (index in 0..list.size step 2) {}
for (index in (0..list.size).reversed() step 2) {}
// 相当于 for(int index = 0, k = list.size(); index < k, i+=2)

// 递减进步迭代
for (index in list.size downto 0 step 2) {}
// 相当于 for(int index = list.size(); index > 0, i-=2)

// key值循环
for ((key, value) in map){
    print("the element at $key is $value")
}

if else

var max: Int

if (a > b) {
    max = a
} else {
    max = b
}

// 单表达式
if (a > b) max = a else max = b

// 或者
max = if (a > b) a else b

when

// 带参判断
when (index) {
    0 -> print("index is zero")
    1, 2 -> print("index is one|two")
    in 3..5 -> print("index is three|four|five")
    !in 6..8 -> print("index !is six|seven|eight")
    else -> print("index is other")
}

// 无参判断
var max: Int
var a = 2
var b = 3

when {
    a > b -> max = a
    else -> max = b
}

如上处理可见 when 可代替 if 的使用

while

val list = listOf("one", "two", "three")
var index = 0

while (index < list.size){
    println(list[index])
    index ++
}

do while

var list = ArrayList<String>()
var index = 0

do {
    list.add("demo ${++index}")
} while (index < 100)

for

val list = listOf("one", "two", "three")

// 对象循环
for (str in list){
    println(str)
}

for (str : String in list){
    println(str)
}

// 坐标循环
for (index in list.indices) {
    println("the element at $index is ${list[index]}")
}

for ((index, value) in list.withIndex()) {
    println("the element at $index is $value")
}

forEach

val list = listOf("one", "two", "three")

list.forEach {
    println(it)
}

break return

fun foo(){
    val list = listOf("one", "two", "three")

    flp@ for(str in list)  {
        // 结束 for 循环
        // if (str.isEmpty()) break

        // 结束 for 循环(嵌套可@注释指定)
        // if (str.isEmpty()) break@flp

        print(str)
    }

    list.forEach lfe@ {
        // 循环结束,后继代码不执行
        // if(it.isEmpty()) return

        // 仅本次循环结束,同 continue(嵌套可@注释指定)
        // if(it.isEmpty()) return@forEach
        // if(it.isEmpty()) return@lef
    }
}

基本类型

等式

// 除 0-127 以外的数值
val num1: Int = 10000
val num2: Int = 10000
val num3: Int? = num1
val num4: Int? = num1

println("num1 == num2:${num1 == num2}")
// num1 === num2// 无需这么判断,这里编译器会自行处理

// 以下效果相同
println("num3 == num4:${num3 == num4}")// 反之用 !=
// num3?.equals(num4)

println("num3 === num4:${num3 === num4}")// 反之用 !==

=== 表示对象与结构上的判断,== 仅表示结构上的判断

log:
num1 == num2 :true
num3 == num4:true
num3 === num4:false

显示转换

toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char

val a: Long = 1
val b: Int = a.toInt()

数组

Array
ByteArray
IntArray
ShortArray

val strArr: Array<String>? = Array(3, { i -> i.toString() })// ["1","2","3"]
val shortArr: ShortArray? = shortArrayOf(1, 2, 3)
val intArr: IntArray? = intArrayOf(1, 2, 3)
val byteArr: ByteArray? = byteArrayOf(1, 2, 3)

字符串

val shortStr = "这里是\"短\"字符串"

val longStr1 = """
    这里是"长"字符串,这里面不能放转义字符
"""

val longStr2 = """
    |去掉这句话前面的空格
""".trimMargin()

val lognStr3 = """
    >去掉这句话前面的空格,自定义标识符
""".trimMargin(">")

val longStr4 = """
    去掉这句话前面的空格,效果同上
""".trim()

字符串模板

val im = "异端纪要"
print("Kotlin $im (${im.length})")

输出结果:Kotlin 异端纪要 (4)

其他

操作符

集合

操作符 描述 实例
any 至少有一个元素符合给出的判断条件,返回 true list.any { it % 2 == 0 }
all 全部的元素符合给出的判断条件,返回 true list.all { it < 10 }
count 返回符合给出判断条件的元素总数 list.count { it % 2 == 0 }
fold 一个初始值的基础上从第一项到最后一项通过一个函数累计所有的元素 list.fold(4) { total, next -> total + next }
foldRight 与 fold 一样,但是顺序是从最后一项到第一项 list.foldRight(4) { total, next -> total + next }
forEach 遍历所有元素,并执行给定的操作 list.forEach { println(it) }
forEachIndexed 与forEach,但是我们同时可以得到元素的index list.forEachIndexed { index, value -> println(“position $index contains a $value”) }
max,maxBy 返回(函数判定)最大的一项,没有则返回 null list.max()
min,minBy 返回(函数判定)最小的一项,没有则返回 null list.minBy { -it }
none 如果没有任何元素与给定的函数匹配,返回 true list.none { it % 7 == 0 }
reduce 通过一个函数从第一项到最后一项进行累计 list.reduce { total, next -> total + next }
reduceRight 与 reduce 一样,但是顺序是从最后一项到第一项 list.reduceRight { total, next -> total + next }
sumBy 返回所有每一项通过函数转换之后的数据的总和 list.sumBy { it % 2 }

操作符 描述 实例
drop 返回包含去掉前 n 个元素的所有元素的列表 list.drop(4)
dropWhile 返回根据给定函数从第一项开始去掉指定元素的列表 list.dropWhile { it < 3 }
dropLastWhile 返回根据给定函数从最后一项开始去掉指定元素的列表 list.dropLastWhile { it > 4 }
filter 过滤所有符合给定函数条件的元素 list.filter { it % 2 == 0 }
filterNot 过滤所有不符合给定函数条件的元素 list.filterNot { it % 2 == 0 }
filterNotNull 过滤所有元素中不是 null 的元素 list.filterNotNull()
slice 过滤一个 list 中指定 index 的元素 list.slice(listOf(1, 3, 4))
take 返回从第一个开始的 n 个元素 list.take(2)
takeLast 返回从最后一个开始的n个元素 list.takeLast(2)
takeWhile 返回从第一个开始符合给定函数条件的元素 list.takeWhile { it < 3 }

操作符 描述 实例
flatMap 遍历所有的元素,为每一个创建一个集合,最后把所有的集合放在一个集合中 list.flatMap { listOf(it, it + 1) }
groupBy 返回一个根据给定函数分组后的 map list.groupBy { if (it % 2 == 0) “even” else “odd” }
map 返回一个每一个元素根据给定的函数转换所组成的 List list.map { it * 2 }
mapIndexed 返回一个每一个元素根据给定的包含元素index的函数转换所组成的List list.mapIndexed { index, it -> index * it }
mapNotNull 返回一个每一个非 null 元素根据给定的函数转换所组成的 List list.mapNotNull { it * 2 }

操作符 描述 实例
contains 如果指定元素可以在集合中找到,返回 true list.contains(2)
elementAt 返回给定 index 对应的元素,如果 index 数组越界则会抛出 IndexOutOfBoundsException list.elementAt(1)
elementAtOrElse 返回给定 index 对应的元素,如果index数组越界则会根据给定函数返回默认值 list.elementAtOrElse(10, { 2 * it })
elementAtOrNull 返回给定 index 对应的元素,如果 index 数组越界则会返回 null list.elementAtOrNull(10)
first 返回符合给定函数条件的第一个元素 list.first { it % 2 == 0 }
firstOrNull 返回符合给定函数条件的第一个元素,如果没有符合则返回 null list.firstOrNull { it % 7 == 0 }
indexOf 返回指定元素的第一个 index,如果不存在,则返回-1 list.indexOfFirst { it % 2 == 0 }
indexOfLast 返回最后一个符合给定函数条件的元素的index,如果没有符合则返回-1 list.indexOfLast { it % 2 == 0 }
last 返回符合给定函数条件的最后一个元素 list.last { it % 2 == 0 }
lastIndexOf 返回指定元素的最后一个 index,如果不存在,则返回-1 list.last { it % 2 == 0 }
lastOrNull 返回符合给定函数条件的最后一个元素,如果没有符合则返回 null list.lastOrNull { it % 7 == 0 }
single 返回符合给定函数的单个元素,如果没有符合或者超过一个,则抛出异常 list.single { it % 5 == 0 }
singleOrNull 返回符合给定函数的单个元素,如果没有符合或者超过一个,则返回 null list.singleOrNull { it % 7 == 0 }

操作符 描述 实例
merge 把两个集合合并成一个新的,相同index的元素通过给定的函数进行合并成新的元素作为新的集合的一个元素,返回这个新的集合。新的集合的大小由最小的那个集合大小决定 list.merge(listRepeated) { it1, it2 -> it1 + it2 }
partition 把一个给定的集合分割成两个,第一个集合是由原集合每一项元素匹配给定函数条件返回true的元素组成,第二个集合是由原集合每一项元素匹配给定函数条件返回 false 的元素组成 list.partition { it % 2 == 0 }
plus 返回一个包含原集合和给定集合中所有元素的集合 list.plus(listOf(7, 8))
或 list + listOf(7, 8)
zip 返回由 pair 组成的 List,每个 pair 由两个集合中相同 index 的元素组成。这个返回的List的大小由最小的那个集合决定 list.zip(listOf(7, 8))
unzip 从包含pair的List中生成包含 List 的 Pair listOf(Pair(5, 7), Pair(6, 8)).unzip()

操作符 描述 实例
reverse 返回一个与指定 list 相反顺序的 list list.reverse()
sort 返回一个自然排序后的 list list.sort()
sortBy 返回一个根据指定函数排序后的list list.sortBy { it % 3 }
sortDescending 返回一个降序排序后的 list list.sortDescending()
sortDescendingBy 返回一个根据指定函数降序排序后的 list list.sortDescendingBy { it % 3 }

This 表达式

fun main(args: Array<String>) {
    A().B().output()
}

class A {
    inner class B {
        fun output(){
            "Kotlin".foo()
        }

        fun String.foo() {
            println("foo this@A > ${this@A}")
            println("foo this@B > ${this@B}")

            println("foo this > $this")
            println("foo this@foo > ${this@foo}")

            val funLit = fl@ fun String.() {
                println("funLit this > $this")
            }
            "Android".funLit()

            val funLit2 = { s: String ->
                println("funLit2 this > $this")
            }
            funLit2("Java")
        }
    }
}

log:
foo this@A > packname.A@29453f44
foo this@B > packname.A$B@5cad8086
foo this > Kotlin
foo this@foo > Kotlin
funLit this > Android
funLit2 this > Kotlin

注解

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
        AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class Kat// 关键字-annotation
// annotation class Kat(val why: String)// 带参数注解
@Kat class Test {
    @Kat fun baz(@Kat foo: Int): Int {
        return (@Kat 1)
    }
}

反射

class Test(val title: String)

var value = 1

val String.lastChar: Char
    get() = this[length - 1]

fun isOdd(x: Int) = x % 2 != 0

fun length(s: String) = s.length    

fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}

fun function(factory: (str: String) -> Test) {
    val x: Test = factory("Kotlin")
    println("构造函数引用:${x.title}")
}

fun main(args: Array<String>) {
    println("类引用:${Test::class}")

    print("属性引用:${::value.get()},")
    ::value.set(2)
    println("$value")

    function(::Test)

    println("函数引用:${listOf(1, 2, 3).filter(::isOdd)}")

    val oddLength = compose(::isOdd, ::length)
    println("函数组合引用:${listOf("a", "ab", "abc").filter(oddLength)}")

    println("函数扩展引用:${String::lastChar.get("Kotlin")}")
}

log:
类引用:class packname.Test
属性引用:1,2
构造函数引用:Kotlin
函数应用:[1, 3]
函数组合引用:[a,abc]
函数扩展引用:n

工具

Gradle

这里仅基于 Android 开发下 Android Studio 的配置实现(版本检查更新),其他请移步到最后参考文档中进一步了解

// project/build.gradle
buildscript {
    ext {
        kotlin_version = '1.1.2-3'
        gradle_version = '2.3.0'
    }
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:$gradle_version"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
// app/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
    ...
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }
}

dependencies {
    ...
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

猜你喜欢

转载自blog.csdn.net/u013523377/article/details/72617847