Kotlin基础语法-05-运算符重载-中缀表达式

Kotlin基础语法-05-运算符重载-中缀表达式

接上篇文章本文主要从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. 总结

多上手敲、多尝试、多思考、 有问题评论区我们共同讨论进步。

你可能感兴趣的:(Android,Kotlin,Java)