首页 > 其他分享 >kotlin的流畅性

kotlin的流畅性

时间:2022-11-15 00:12:33浏览次数:35  
标签:val point Int kotlin 运算符 println 流畅性 fun

一、关于运算符的重载

kotlin的运算符重载和c++的运算符重载比较类似,使用operator的方式: operator fun xxx的方式

比如重载类Complex的乘号

data class Complex(val real: Int, val imaginary: Int) {
    operator fun times(other: Complex) =
    Complex(real * other.real - imaginary * other.imaginary,
            real * other.imaginary + imaginary * other.real)

    private fun sign() = if (imaginary < 0) "-" else "+"

    override fun toString() = "$real ${sign()} ${abs(imaginary)}i"
}

println(Complex(4, 2) * Complex(-3, 4))
println(Complex(1, 2) * Complex(-3, 4))

如上所示,重载了两个Complex的乘法,使用times

具体关于各个运算符对应的重载方法名如下所示

如上所示,每个运算符均有对应的运算符重载方法;

那么可能有疑问了,为何kotlin不能完全像c++一样,加号就使用operator fun +() 而是使用了plus呢

是因为:JVM不支持运算符重载(而且kotlin编译成java字节码),kotlin通过将运算符映射到特殊命名的方法,使运算符重载成为可能。

 

二、使用扩展函数注入运算符的方式

1、扩展函数使用运算符

operator fun Pair<Int, Int>.plus(other: Pair<Int, Int>) =
Pair(first + other.first, second + other.second)

如上所述,虽然plus函数在Pair的类外面,但是我们在该位置可以使用加号对两个Pair进行相加

2、使用in运算符

data class Point(val x: Int, val y: Int)
data class Circle(val cx: Int, val cy: Int, val radius: Int)

operator fun Circle.contains(point: Point) =
(point.x - cx) * (point.x - cx) + (point.y - cy)*(point.y - cy) < radius * radius

val circle = Circle(100, 100, 25)
val point1 = Point(110, 110)

println(circle.contains(point1))
println(point1 in circle)

如上所示,通过增加operator标识符,使得contains可以使用in来表示,更像自然语言

如果打算使用中缀表达式,则可以使用infix 关键字:如下所示

infix fun Circle.contains(point: Point) =
(point.x - cx) * (point.x - cx) + (point.y - cy)*(point.y - cy) < radius * radius


println(circle contains point1)

如上所示,则是实用中缀的方式;如果要同时使用operator和infix也是可以的:operator infix fun Circle.contains(point: Point) = 。。。。。

 

 

三、关于四种方法的行为:let、also、run、apply

先总结各个方法的用法:

let:有一个context参数,并返回对应的计算结果

also:有一个context参数,并返回context参数

run:无参数,返回结果

apply:无参数,并返回context

》》个人理解:context即使用this,更细节的就不去深究了

 

例子,如下为了计算,只使用了from和send两个函数:

class Mailer {
    val details = StringBuilder()
    fun from(addr: String) = details.append("from $addr...\n")
   fun to(addr: String) = details.append("to $addr...\n") fun send() = "...sending...\n$details" }

正常的调用逻辑:

val mailer = Mailer()
mailer.from("[email protected]") // 先构造完,这里为了简单只使用from构造,其实还有to,body等构造
mailer.to("[email protected]") val result = mailer.send() println(result)

 

但是我们可以使用apply进行简化代码

val mailer1 = Mailer()
.apply{from("[email protected]")}
.apply{to("[email protected]")}
val result1 = mailer1.send()
println(result1)

因为apply是无参,并且返回this,所以可以调用多个;我们也可以将上述的两个apply合并

val mailer1 = Mailer()
.apply {
from("[email protected]")
to("[email protected]")
}

那么如果要将send也合并到一起呢? 因为send是返回String类型所以可以使用run的方式

val result2 = Mailer().run {
    from("[email protected]")
    to("[email protected]")
    send()
}
println(result2)

如上,通过最后send返回的是String,返回给result2

 

同理,let和also也是差不多,只是let会将this作为参数传给lambda

 

四、关于隐式接收方

var length = 100
val printIt: (Int) -> Unit = {n: Int ->
    println("n is $n, length is $length")
}
printIt(6)

如上函数的打印结果是:n is 6, length is 100

但是我们如果要打印字符串的长度,则可以使用隐式的方式

val printIt: String.(Int) -> Unit = {n: Int ->
    println("n is $n, length is ${this.length}")
}

printIt("Hello", 6)
"Hello".printIt(6)

如上的两种方式均能否正常调用printIt函数,并且返回的结果是一样的

 

标签:val,point,Int,kotlin,运算符,println,流畅性,fun
From: https://www.cnblogs.com/czwlinux/p/16891040.html

相关文章

  • 又一巨头从 Java 迁移到 Kotlin,简直很无语。。
    出品|OSC开源社区(ID:oschina2013)Meta发布了一篇博客表示,正在将其Android应用的Java代码迁移到Kotlin,并分享了这一过程中的一些经验。该公司认为,Kotlin是一种流......
  • Mp3文件标签信息读取和写入(Kotlin)
    原文:Mp3文件标签信息读取和写入(Kotlin)-Stars-One的杂货小窝最近准备抽空完善了自己的星之小说下载器(JavaFx应用),发现下载下来的mp3文件没有对应的标签也是了解可以......
  • kotlin 内部迭代和延迟计算
    一、内部的迭代函数filter(e->返回true和false)判断数值是否加入新的数组map(e->返回调整e之后的值)对数组中每个数进行调整,并存入新的数组reduce(total,e->返回......
  • kotlin lambda
    一、lambda表达式的语法{parameterlist->body}kotlin和java的lambda表达式的语法存在一定程度的差异:1、kotlin在通常的情况下不允许有return语句,而java则可以有零个......
  • Android开发Compose版本、Kotlin 版本、KSP版本版本对应关系
    Android开发Compose版本、Kotlin版本、KSP版本版本对应关系是要遵循官方给出的,不然容易出锅甚至编译都不过,即使编译通过也可能导致潜在崩溃ComposeCompiler版本和兼......
  • Kotlin 中的 Lambda 与 Inline
    在Kotlin中,有很多很酷很实用的特性,比如Lambda和高阶函数,利用这些特性,我们可以更加快速的实现开发,提升效率。比如我们实现一个捕获Throwable,安全执行部分代码的高阶函数fun......
  • 探究Kotlin的局部方法
    在Kotlin中,定义方法很有趣,不仅仅因为方法的关键字是fun(function前几个字符),还是因为你会惊奇的发现,它允许我们在方法中定义方法。如下funmethodA(){funmethodB(){......
  • 有点意思的Kotlin的默认参数与JVMOverloads
    在Java中,当我们定义一个类的时候,总会出现一些变量是必须要填写的,而另一些是可选的。比如像下面这样,我们定一个Person类,其中name是必须填写的,而性别sex和isChinese可选,如果不......
  • kotlin 委托
    我们经常使用的其实是继承,但是相对于继承使用委托的耦合性会更低。使用继承则代码相对会比较简单,但是使用委托则会比较复杂一、假设有interfaceWorker、classJavaProgr......
  • JvmMultifile 注解在 Kotlin 中的应用
    接触过Kotlin之后,我们会利用其扩展方法特性创建很多便捷的方法来实现更好更快的编码。比如我们对于RxJava进行一些简单的扩展方法实现。下面的这段代码实现一个将任意的对象......