Kotlin 扩展属性、扩展函数

Kotlin ---- 扩展属性、扩展函数

在原有类的基础上,增加功能,及不用改源码,也不用写子类!

简单的示例

扩展属性
val Float.dpTOpx
    get()= TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,this,
        Resources.getSystem().displayMetrics)

val Float.pxTOdp
get() = this/Resources.getSystem().displayMetrics.density+0.5f
println("转换结果dpTOpx${200f.dpTOpx}")
println("转换结果pxTOdp${200f.pxTOdp}")

高级用法 扩展函数

上面的扩展属性,我们都比较容易上手,但是 扩展函数+函数引用混在一起,很多人就会搞蒙圈了

下面我们就来把它 讲清楚:

作用域

其实写在哪都可以(直接放在顶层目录下作为一个 Top-level Function),但是由于不应该给协同开发的同事,造成打扰,我们应该写在

自己的工作package下 (com.zyg.myTest下)或者某个文件下。

给扩展函数 指定 一个Receiver (接受者)

Receiver 也就是说,指定谁能调用 这个函数。

归属问题

在一个类中去写一个扩展函数


class ExampleTest {
    fun  String.method2(int:Int){
        println(this+int)
    }
	  ...
        "翻滚吧章鱼".method2(2020) // print-> "翻滚吧章鱼2020"
    }

那么他就是 ExampleTest 这个类的成员函数,只能在类的内部调用。

引用问题

lambda 中 函数可以通过 ‘’ :: " 双冒号被指像的 (指像的并不是 函数本身,而是跟函数有相同功能的 ‘对象’ )。

那么‘扩展函数同样可以通过“ :: ”被指像 ’ (PS: 但这个方法 需要是 Top-level Function,类的成员函数则不行 )。

示例
fun String.method1(i:Int){
    println("method1${i}")
}
...
(String::method1)("翻滚吧章鱼",1) //kotlin 将第一个参数,Receiver调用者传进去 ; 后面的参数则为 方法的入参

ps: 可能有同学会问,为什么第一个参数要传 调用者 Receiver 呢?

因为 我们 拿到的是 函数引用的对象,而不是调用者的对象,我们不可能写成 「 “翻过滚吧章鱼”::method1」对吧。。。

那么kotlin 提供的途径就是,在这种调用情况下,增加一个函数参数,并且‘函数调用者’放在第一个参数

这样我们就可以,用函数引用来调用,成员函数 和 扩展函数了。

引用赋值

可以复制给 两种 不同的函数变量类型 :有 Receiver 和 无 Receiver 的

val a:String.(Int) -> String = String::method1   // 有
val b:(String,Int) -> String = String::method1   // 无

这两种类型的 变量也可以相互转换

val a:String.(Int) -> String = String::method1
val b:(String,Int) -> String = String::method1
val c:(String,Int) ->String = a
val d:String.(Int) ->String = b
A. 等等,既然能相互转换,是不是说明,无Receiver 的函数引用,也可以赋值给有Receiver 的变量么?

我有一个大胆的想法:

fun method3(s:String,i:Int):String{
    return s+i
}
...
val e:(String,Int) ->String = ::method3
val f:String.(Int) ->String = ::method3

竟然没报错!!!

那这样的话,我们就可以将一个 普通的函数,使用Receiver 的方式来调用,这个可太爽了吧!

ps:使用的前提的 普通函数的第一个参数类型,要与Receiver 的类型相同。

"翻滚吧章鱼".f(101) // 可以调用
"翻滚吧章鱼".method3(101) // 这样会报错
B.同时反响操作也可以的,但是好像没什么用了(有Receiver 的函数引用,也可以赋值给无Receiver 的变量)

总结

本文涉及内容

  • 扩展函数
  • 扩展函数的引用
  • 有无Reveiver 的函数类型的转换以及 扩展属性

你可能感兴趣的:(android,kotlin)