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
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<*> 或这它的父类
// 单线程执行,多个线程使用,尽在一个线程完成初始工作
// 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
初始工作仅发生在属性被第一使用时,以后每次调用只简单返回之前存储的值
// 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
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
}
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"
}
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")
}
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 (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 的使用
val list = listOf("one", "two", "three")
var index = 0
while (index < list.size){
println(list[index])
index ++
}
var list = ArrayList<String>()
var index = 0
do {
list.add("demo ${++index}")
} while (index < 100)
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")
}
val list = listOf("one", "two", "three")
list.forEach {
println(it)
}
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 } |
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
这里仅基于 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"
}