接上篇文章本文主要从kotlin 中的运算符重载、中缀表达式、反引号与typealies、 对象比较与值比较、DSL的基本概念、
1.运算符重载
来看一段代码
fun main( args : Array){
/// 这里的step 就是步进、中缀表达式。
for( i in 1..1000 setp 20 ){
print("$i")
}
}
编译后就会in就会被编译成一个Int迭代器, 稍有基础就能看懂、 不再赘述、
override fun iterator(): IntIterator = IntProgressionIterator(ifrst, last, step)
internal class IntProgressionIteraotr(first: Int, last: Int, val step : Int):IntIterator{
private var next = first
private val finalElement = last
private var hasNext :Boolean if (step>0) first <=last else first > = last
override fun hasNext(): Boolean = hasNext
override fun nextInt():Int{
val value = next
if(value == finalElement){
hasNext = false
}else{
next += setp
}
return value
}
}
kotlin 中的运算符重载使用的是operator 关键字实现、修饰fun 时候后、 表示重载了函数名指代的运算符、
在结构的时候 ,我们标记过:
operator : 将一个函数标记为重载一个操作符或者实现一个约定。
再来一段代码
for( i in 1.rangeTo 20 ){
println("$i")
}
运算符的重载只能是在kotlin中定义好的、不能凭空来造。运算符是有上限的、
现在一共有120几个吧、
/// 看到了吧、这就是运算符重载的方法、
public operator fun rangeTo(other: Int) : IntRange
// 当然还有String + 号 也是重载
public opterator fun plus(other:Any?):String
2.中缀表达式
当然如果重载运算符不够用、这时候就需要使用中缀表达式
来个例子,
fun main(args: Array) {
println(5 vs 6)
println(5.7 vs 2.3)
}
/**
* 密闭类的三个值、
*/
sealed class CompareResult {
object MORE : CompareResult() {
override fun toString(): String {
return "more"
}
}
object LESS : CompareResult() {
override fun toString(): String {
return "less"
}
}
object EQUAL : CompareResult() {
override fun toString(): String {
return "equal"
}
}
}
/**
* Int 是该函数的接受者类型、也就是说只能是该类型可以调用该方法
*/
infix fun Int.vs(num: Int): CompareResult {
if (this - num < 0) {
return CompareResult.LESS
} else if (this - num > 0) {
return CompareResult.MORE
} else {
return CompareResult.EQUAL
}
}
infix fun Float.vs(num:Float):CompareResult=
if(this-num<0){
CompareResult.LESS
}else if(this- num>0){
CompareResult.MORE
}else{
CompareResult.EQUAL
}
infix fun Double.vs(num:Double):CompareResult=
if(this-num<0){
CompareResult.LESS
}else if(this - num >0){
CompareResult.MORE
}else{
CompareResult.EQUAL
}
打印结果:
less
more
Process finished with exit code 0
一个函数只有用于两个角色类似的对象时才将其声明为中缀函数。
推荐: and 、 to 、 zip
反例: add
最重要的一点:
如果一个方法会改动其接受者,那么不要声明为中缀表达式。
3. kotlin 的反引号``与typealies 和对象比较与值比较
///
fun `123456`():Unit{
println("test1")
}
123456一群数字肯定是没有意义的, 在java中也不能够作为一个方法名称,但是在kotlin中添加了``引号,则可以作为一个方法名使用,而且可以正常的调用。
注意: 这种写法只用于kotlin中,而且不推荐使用。因为调用起来很操心, 不省心。
例如``中间是一个空格,两个空格也是一个方法,这时候可能因为编程习惯多打了一个空格而造成调用方法的不同, 同时这么写也不能够让java代码调用。
public typealias A = File
fun main(args: Array){
///// 这么声明是合法的,
var a : File = A("/kotlinlearn/dev/xxx.json")
}
有一种类似于C/C++ 中的define 、宏定义的感觉。
再找一下koltin中类似映射的,例如:
@SinceKotlin("1.1") public typealias Error = java.lang.Error
@SinceKotlin("1.1") public typealias Exception = java.lang.Exception
@SinceKotlin("1.1") public typealias RuntimeException = java.lang.RuntimeException
@SinceKotlin("1.1") public typealias IllegalArgumentException = java.lang.IllegalArgumentException
@SinceKotlin("1.1") public typealias IllegalStateException = java.lang.IllegalStateException
@SinceKotlin("1.1") public typealias IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException
@SinceKotlin("1.1") public typealias UnsupportedOperationException = java.lang.UnsupportedOperationException
@SinceKotlin("1.1") public typealias NumberFormatException = java.lang.NumberFormatException
@SinceKotlin("1.1") public typealias NullPointerException = java.lang.NullPointerException
@SinceKotlin("1.1") public typealias ClassCastException = java.lang.ClassCastException
@SinceKotlin("1.1") public typealias AssertionError = java.lang.AssertionError
@SinceKotlin("1.1") public typealias NoSuchElementException = java.util.NoSuchElementException
@SinceKotlin("1.1") public typealias Comparator = java.util.Comparator
这里有一部分kotlin 中的类,映射的java中的类, 这样就形成了隔离层,既保留了java中的特性,又方便了kotlin 中的维护。
4. kotlin中如何比较对象
我们知道在java中A==B代表的意思是对象A与对象B是否相同,比较的是堆内存地址是否相同。
而例如String 的equals 代表的意思是对象A与对象B的值是否相同。
其实记住这句话就行了, 但是在kotlin中A == B代表的是对象A与B的值是否相同,而A===B则表示对象A与对象B是否是相同的对象
5. 外部DSL与内部DSL
什么是DSL语言, 怎么还区分外部和内部?
很简单, DSL 就是(Domain Specific Language ) 领域专用语言。例如json , xml , css, makefile, anko,kolley, build.gradle 这些就是。
外部内部的区分就是, 不依赖其他语言而且能都独自定义的就是外部的, 反之就是内部的。
举个例子,
例如json 就是表达了数据传输格式。 xml 既表达数据格式,也可以表示配置, 重要的是不依赖外部语言。
而anko ,kolley 就严重依赖了kotlin 才能够使用的,
例如anko 就是基于kotlin开发的
能够类似于butterknife的一个框架。 而kolley 则是类似于volley的一个网络请求架构。
注意, 不管内部DSL还是外部DSL 其特点是专有的,特殊领域内使用的,不要求复杂,包含所有,只要求精而专一。
6. 总结
多上手敲、多尝试、多思考、 有问题评论区我们共同讨论进步。