首页 > 其他分享 >解析Kotlin中扩展函数与扩展属性【笔记摘要】

解析Kotlin中扩展函数与扩展属性【笔记摘要】

时间:2024-07-03 19:28:15浏览次数:10  
标签:调用 函数 Int Kotlin 摘要 扩展 Example String

1.扩展函数

1.1 作用域:扩展函数写的位置不同,作用域就也不同

扩展函数可以写成顶层函数(Top-level Function),此时它只属于它所在的 package。这样你就能在任何类里使用它:

package com.rengwuxian

fun String.method1(i: Int) {
  ...
}
...
"rengwuxian".method1(1)

扩展函数也可以写在某个类里。然后你就可以在这个类里调用这个函数,但还是必须使用那个前缀类的对象来调用它:

class Example {
  fun String.method2(i: Int) {
    ...
  }
  ...
  "rengwuxian".method2(1) // 可以调用
}

注意:它属于Example的成员函数(限定该函数的调用范围),又属于String的扩展函数(限定该函数可以被谁调用)

1.2 指向扩展函数的引用

扩展函数如果是Top-Level的话,可以被引用;但是是某个类的成员函数,那就不可以被引用了:

fun String.method1(i: Int) {
    ...
}
...
String::method1

1.3 调用扩展函数的引用

直接调用或者用 invoke() 都可以,不过要记得把 Receiver 也就是接收者或者说调用者填成第一个参数

(String::method1)("rengwuxian", 1)
String::method1.invoke("rengwuxian", 1)

// 以上两句都等价于:
"rengwuxian".method1(1)

1.4 把扩展函数的引用赋值给变量

同样的,扩展函数的引用也可以赋值给变量:

val a: String.(Int) -> Unit = String::method1

然后你再拿着这个变量去调用,或者再次传递给别的变量,都是可以的:

"rengwuxian".a(1)
a("rengwuxian", 1)
a.invoke("rengwuxian", 1)

1.5 有无 Receiver 的变量的互换

class Example {
    fun happy(i: Int) {

    }
}
fun Example.sad(i: Int) {

}

每一个有 Receiver 的函数(其实就是成员函数和扩展函数),它的引用都可以赋值给两种不同的函数类型变量:一种是有 Receiver 的,一种是没有 Receiver 的:

val n: (Example, Int) -> Unit = Example::happy
val m: Example.(Int) -> Unit = Example::happy
var x: (Example, Int) -> Unit = Example::sad
var y: Example.(Int) -> Unit = Example::sad
x = m
y = n

1.6 改变原本的性质,使其可能无法被允许调用

一个普通的无 Receiver 的函数也可以直接赋值给有 Receiver 的变量:

fun mad(e: Example, i: Int) {

}
...

val e: (Example, Int) -> Unit = ::mad
val f: Example.(Int) -> Unit = ::mad

通过这些类型的互相转换,你可以把一个本来没有 Receiver 的函数变得可以通过 Receiver 来调用:
Example().mad(1)  //不允许调用,报错
Example().e(1)  //不允许调用,报错
Example().f(1)  //允许调用

当然了你也可以反向操作,去把一个有 Receiver 的函数变得不能用 Receiver 调用:

fun Example.sad(i: Int) {

}
...

val g: (Example, Int) -> Unit = Example::sad
val h: Example.(Int) -> Unit = Example::sad
Example().sad(1)  //允许调用
Example().g(1)  //不允许调用,报错
Example().h(1)  //允许调用

2.扩展属性

2.1 扩展变量与扩展常量

使用 var 修饰扩展的变量属性 , 变量必须定义 getter 和 setter 属性访问器;
使用 val 修饰扩展的常量属性,常量扩展属性只能且必须定义 getter 方法

2.2 定义位置

class Example {
    var name: String = "Tom"
    var age: Int = 18
}

和扩展函数一样,扩展属性可以定义在Top-level,也可以定义在某个类中
定义在Top-level,那么全局都可以使用该属性:

var Example.olderAge: Int
    get() {
        return this.age + 1
    }
    set(value) {
        this.age = value -1
    }

val Example.nameAndAge: String
    get() {
        return "${this.name} : ${this.age}"
    }

定义在某个类中,那么只能在该类中使用:

class Example {
    var name: String = "Tom"
    var age: Int = 18
    
    var Example.olderAge: Int
        get() {
            return this.age + 1
        }
        set(value) {
            this.age = value -1
        }

    val Example.nameAndAge: String
        get() {
            return "${this.name} : ${this.age}"
        }
}

2.3 扩展属性没有幕后字段

扩展属性由于没有幕后字段 , 因此不能定义属性的初始化器 ,给扩展属性赋初值会报以下错误:
在这里插入图片描述

扩展属性没有幕后字段不能保存实际的字段值 , 其属性访问器中只能调用对象中的属性和方法 , 不能调用扩展属性本身


参考文章:
会写「18.dp」只是个入门——Kotlin 的扩展函数和扩展属性(Extension Functions Properties)

标签:调用,函数,Int,Kotlin,摘要,扩展,Example,String
From: https://blog.csdn.net/weixin_40261082/article/details/140096779

相关文章

  • 真太卷了...又开源一款开放API管理工具,支持扩展插件(带私活源码)
     关于API管理工具,相信大家已经都有自己用着顺手的。像国外的Postman,国内有Apifox等等。今天给大家分享的是近期在GitHub比较热门的另一款开放API管理工具:Eoapi。1.Eoapi简介概括来说:这是一款API管理工具,支持扩展插件,简单,开源。Eoapi集合了基础的API管理功能和测试......
  • 信息摘要技术
    信息摘要定义信息摘要就是原数据通过某个算法生成一个固定长度的单向散列值。特点1、输出长度固定:无论输入的长度和值如何,计算得到的哈希值长度总是固定的。2、不可逆性(单向):不可能使用散列值推出原文件内容3、无碰撞性:想要找到两个不同的输入值,使它们哈希后相同是非常困难的......
  • DevExpress WPF中文教程:Grid - 如何显示摘要(设计时)?
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为中心......
  • 【转】[VS2022] 给下载扩展提速
    使用:https://tool.chinaz.com/dns参考:https://blog.51cto.com/xiaohaiwa/5681372步骤:1、在https://marketplace.visualstudio.com下载扩展,然后在Chrome浏览器的下载记录里对正在下载的任务,复制它的域名2、进 https://tool.chinaz.com/dns站长工具网站,查这个域名的响应......
  • Eureka的自扩展之道:服务自动扩展的秘诀
    ......
  • 构建可扩展性强的返利App后端服务架构
    构建可扩展性强的返利App后端服务架构大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在构建返利App的后端服务时,可扩展性是一个至关重要的考量因素。随着用户量的增长和业务的扩展,系统需要能够灵活地调整和扩......
  • 欧拉函数、整除分块和扩展欧几里得
    欧拉函数欧拉函数(写作\(\varphi(x)\)),表示\(i\in[1,x]且\gcd(i,x)=1\)的\(i\)的数量。乍一看好像很难求,但我们先考虑最简单的情况,即\(x\in\mathbb{P}\)(\(\mathbb{P}\)表示质数集)的情况。首先很容易看出\(\varphi(x)=x-1\),因为\(x\in\mathbb{P}\),所以\(\foralli......
  • Kotlin作用域函数it和with的使用场景
    在Kotlin中,apply、run、with使用this,而let和also使用it,这背后的原因是为了提供灵活性和代码清晰度。不同的作用域函数有不同的设计目的,选择使用this或it是为了适应不同的使用场景。以下是详细解释:使用this的作用域函数apply设计目的:主要用于配置对象。使用th......
  • Linux 文件系统扩展
    今天发现/usr目录空间不够。需要扩展。之前没有处理过。今天试了一下调整。并且记录下来整个过程。1使用fdisk-l查看磁盘信息2、使用fdisk/dev/sda对磁盘进行分区操作完后,多了一个/dev/sda34使用pvcreate/dev/sda3创建物理卷5、使用vgextendol/dev/sda3扩展磁......
  • 扩展运算符`...`
    在JavaScript中,...符号在函数定义中被称为“扩展运算符”(spreadoperator)。当你在函数的参数列表中看到...,它表示这个函数可以接受任意数量的参数,并将这些参数作为一个数组传递给函数。在提供的函数定义中:function连续判断(...参数){//...}...参数表示连续判断......