赞
踩
fun main(args : Array<String>){ val user = User(12,"name") val (age,name) = user println(age) println(name) } calss User(var age:Int,var name:String){ //component 是固定写法,在后面跟的数字,表示对应结构体的第几个变量 operator fun component1() = age operator fun component2() = name } operator : 将一个函数标记为重载一个操作符或者实现一个约定 应用场景:在遍历一个map集合的时候可以使用解构,可以同时获取到key 和 vul, 例如下 val map:Map<String,String> =mapOf<String,String>{"key" to "key","vul" to "vul"} for((k,v) in map){ println("key=$key vul=$vul") }
var count:Int for(count = 0; count < 10; count++){ //.... } 上述类似java的for循环,在kotlin 中是没有的。但kotlin 提供了更强大的。如下 //i变量,用于迭代 1..10 表示从1-10的一个区间 for(i in 1..10){ println(i) } //上述 ..区间 最后会被until 这个函数重写 for(i in 1 until 10){ println(i) } // downTo 函数表示递减 从10到1递减 for(i in 10 downTo 1){ println(i) } //setp 函数表示步径 每次增幅为2 for(i in 1..10 setp 2){ println(i) //println 输出结果:1 3 5 7 9 } //kotlin 自定义的一个高阶函数 闭包中it 是一个计数器,表示循环到第几步了 //重复执行当前闭包 repeat(10){ println(it) } val list : ArrayList<String> =arrayListOf<String>{"a","b"} for(str in list){ println(str) } //使用map 是可以直接通过结构拿到key,vul。而list需要调用withIndex 才可以拿到index for((index,str) in list.withIndex()){ println("第${index}个元素是 $str") }
val list =arrayListOf<Char>{'a','b','c'} //.map 操作符可以将 val a = list.map {it - 'a'} .filter {it > 0} //过滤 .find {it > 1} //查找第一个匹配的结果 fun main(args:Array<String>){ val a : Array<String> = arrayOf("4","0","h","d") val index : Array<String> = arrayOf(0,4,5,7,8,3,6) index.filter{//取a.size 长度的 index 元素 it < a.size }.map{//将传入的it ,返回为一个string a[it] }.reduce{s,s1 -> //将两个值合并 "$s$s1" }.also{//最终结果 println("$it") } }
其实kotlin 的所有操作符,都是以inline (内联函数)的扩展函数来实现的。例如下
//将输入的T类型 转换为E类型
inline fun <T,E> Iterable<T>.convert(action:(T) -> (E)):Iterable<E>{
val list:MutableList<E> =mutableListOf()
for(item:T in this) list.add(action(item))
return list
}
fun myQeperator(){
val list: List<Int> =listOf(1,2,3,4,5)
list.convert{
it+1
}.forEach{
println(it)
}
}
是kotlin 内置的一系列可以对数据做一个变换的函数。与集合的操作符相似,但集合的操作符只能用于集合的一系列数据变换。而作用域函数可以应用与所有对象,他可以对所有对象做一系列的操作
//常用的作用域函数有如下 run{...} with(T){...} let{...} apply{...} also{...} object Test { @JvmStatic fun main(){ val user=User("xiaoming") //let 与run 都会返回闭包的执行结果,区别自安于let 有闭包参数,而run 没有闭包参数 var letResult:String =user.let { user: User -> "let::${user.javaClass}" } println(letResult) //this 指代 user(调用者)本身 val runResult:String = user.run { "run: ${this.javaClass}" } println(runResult) //also与apply 都不返回闭包的执行结果,区别在于also 有闭包参数,而apply没有闭包参数 user.also { println("also :: ${it.javaClass}") } user.apply { println("applu :: ${this.javaClass}") } //takeIf 的闭包返回一个判断结果,为false时 takeIf会返回空 user.takeIf { it.name.length>0 }?.also { println("takeIf name:: ${user.name}") }?: println("takeIf 姓名为空") //takeUnless 与takeIf刚好相反,闭包的判断结果为true时函数会返回空 user.takeUnless { it.name.length>0 }?.also { println("takeUnless 姓名为空") }?: println("takeUnless 姓名为: ${user.name}") //with 比较特殊,不是以扩展函数的形式存在的,而是一个顶级函数 with(user){ this.name="with" } } } data class User(var name:String)
元素操作类
contain – 判断是否有指定元素
elementAt – 返回对应的元素,越界会抛出IndexOutOfBoundsExceotion
firstOrNull – 返回符合条件的第一个元素,没有返回null
lastOrNull – 返回符合条件的第一个元素,没有返回null
indexOf – 返回指定元素的下表,没有返回-1
singleOrNull – 返回符合条件的单个元素,如果没有符合或超过一个,返回null
判断类
any – 判断集合中是否有满足条件的元素
all – 判断集合中的元素是否都满足条件
none – 判断集合中是否都不满足条件,是则返回true
count – 查询集合中满足条件的元素个数
reduce – 从第一项到最后一项进行累计
过滤类
filter – 过滤掉所有满足条件的元素
filterNot – 过滤所有不满足条件的元素
filterNotNull – 过滤所有不满足条件的元素
take – 返回前n个元素
转换类
map – 转换成另一个集合(与上面我们实现的convert 方法作用一样)
mapIndexed – 除了转换成另一个集合,还可以拿到Index (下标)
mapNotNull – 执行转换前过滤掉为NUll 的元素
flatMap – 自定义逻辑合并梨啊个集合
groupBy – 按照某个条件分组,返回Map
排序类
reversed – 反序
sorted – 升序
sortedBy – 自定义排序
sortedDescending – 降序
在kotlin 中非常多的运算符都是通过重载来完成的
//其中 1..100中的 .. 便是通过运算符的重载来变成一个区间值的。 //step 既不是关键字也不是函数,类似的就是中缀表达式 fun main(args:Array<String>){ for(i in 1..100 step 20){ println("$i ") } } //编译后,..会被编译成一个迭代器 override fun iterator():IntIterator =IntProgressionIterator(first,last,setp) internal class IntProgressionIterator(first:Int,last:Int,val step:Int):IntIterator{ private var next = first private val finalElement = last private var hasNext:Boolen =if(setp>0) first <=last else first >= last override fun hasNext():Boolen = hasNext override fun nextInt() : Int{ val value = next if(value == finalElement){ hasNext = false }else{ next += step } return value } }
运算符重载 和 中缀表达式本质上都是一个特殊的函数,都是通过函数的调用完成的
运算符的重载是有一个特点的。它一定是提前在kotlin 中定义的,不能凭空重载一个运算符。运算符是有上限的。当运算符不够的时候,我们需要通过中缀表达式扩展
//中缀表达式定义 需要通过infix 来修饰方法。Int 是 vs 函数的函数接收者
infix fun Int.vs(num:Int):CompareResult =
if(this - num < 0){
CompareResult.MORE
}else if(this - num > 0){
CompareResult.LESS
}else {
CompareResult.EQUAL
}
一个函数只有用于两个角色类型的对象时才将其声明为中缀函数
推荐示例:and 、to 、zip 、vs
反例:add
如果一个方法会改动其接收者,那么不要声明为中缀形式
反引号作用:
1.可以用来解决关键字冲突问题
2.将一个不合法的字符串变成合法的 (例如下)
//我们在命名一个函数的时候是不能用纯数字去命名的,必须以下划线或字母开头,然后才能使用数字
使用`` 便可合法化
fun `1234`(){}
fun `` (){}
fun ` `(){}
fun main(args:Array<String>){
`1234`()
` `()
` `()
}
该特性一般不会使用。除非这个类不希望被java 访问到时,
//kotlin 中比较对象和值 java 比较对象和值
a == b 比较值 <==> a.equals(b)
a === b 比较对象 <==> a == b
public typealias A = File
fun main(args:Array<String>){
val a:File=A("")
}
//例如kotlin 中 HasMap 就是通过typealias 来引用的java HashMap
public typealias HasMap<K,V> = java.util.HasMap<K,V>
DSL 分为外部DSL 、和内部DSL
外部DSL(不依赖与其他的编程语言或自然语言)
内部DSL(本省还会依赖于其他编程语言)
DSL优点
提高开发效率
减少沟通成本DSL缺点
很难设计一个通用的DSL
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。