【Kotlin 初学者】扩展-享受编程

2023-05-16

作者简介:CSDN博客专家、华为云·云享专家认证

系列专栏:Kotlin 初学者

学习交流:三人行必有我师焉;择其善者而从之,其不善者而改之。

目录

一、介绍

二、扩展函数

2.1 定义扩展函数

2.1.4 定义超类(Any)扩展函数

2.1.5 泛型扩展函数

三、扩展属性

四、可控类扩展

五、定义扩展文件

5.1 定义扩展文件

5.2 使用

5.3 重命名扩展(import文件别名)

六、()->Unit 和 引用类型.()->Unit


一、介绍

        Kotlin 可以对一个类的属性和函数进行扩展,且不需要继承或使用 Decorator 模式

        扩展是一种静态行为对被扩展的类代码本身不会造成任何影响

二、扩展函数

        扩展函数可以在已有类中添加新的函数,不会对原类做修改。

2.1 定义扩展函数

        扩展可以用于自定义类,也可以用于比如List、String,以及Kotlin标准库里的其他类。和继承相似,扩展也能共享类行为,在你无法接触某个类定义,或者某个类没有使用open修饰符,导致你无法继承它时扩展就是增加类功能最好选择

//定义School类的扩展函数
fun School.student():String{
    return "$name-学习知识"
}
  • School:表示函数的接收者,也就是函数扩展的对象

  • student:扩展函数的名称

  • String:返回类型("$name-学习知识")

        其他的就和定义一般函数类似了。

2.1.1 定义School类

class School(var name:String){
    //自带函数
    fun teacher():String{
        return "$name-教书育人"
    }
}

2.1.2 扩展函数

//定义School类的扩展函数
fun School.student():String{
    return "$name-学习知识"
}
//定义String类的扩展函数
fun String.addSC():String{
    return "$this-帅次"
}

fun main() {
    //School类原来的函数
    println(School("超神学院").teacher())//超神学院-教书育人
    //School类的扩展函数
    println(School("超神学院").student())//超神学院-学习知识
    //String类的扩展函数
    println("Kotlin".addSC())//Kotlin-帅次
}

2.1.3 扩展函数支持范围

        扩展函数定义后在同一个包下可直接调用,在其他包下则需要导入定义的扩展函数。在extension包下定义的扩展函数,在classkotlin包中使用。

        同一包下不能定义同名扩展函数。

import com.scc.kotlin.primary.extension.School
import com.scc.kotlin.primary.extension.addSC
import com.scc.kotlin.primary.extension.student
fun main() {
    println(School("Class包下").student())//Class包下-学习知识
    println("ClassKotlin".addSC())//ClassKotlin-帅次
}

        在多个包下定义扩展函数addSC(),调用时:

2.1.4 定义超类(Any)扩展函数

        因为Any是超类,所以它的扩展函数其他类也能直接使用。这个功能是真的强大。

//定义Any扩展函数
fun Any.eat(): Any {
    return this
}
fun main() {
    //因为Any是超类,所以它的扩展函数其他类也能直接使用
    println("超类".eat())//超类
    println(15.eat())//15
}

        "超类".eat().addSC() 报错

    //报错,因为addSC()函数是String类的扩展函数,Any类无法直接调用
    //除非将 "超类".eat()的返回类型Any转为String再调用。
    "超类".eat().addSC()

        这个时候我们该引入泛型扩展函数了。

2.1.5 泛型扩展函数

        新的泛型扩展函数不仅可以支持任何类型的接收者,还保留了接收者的类型信息,使用泛型类型后,扩展函数能够支持更多类型的接收者,适用范围更广了。

//定义泛型扩展函数
fun <T> T.scww():T{
    return this
}
fun main() {
    //WaKa调用泛型扩展函数scww(),返回String类型调用String类型扩展函数addSC()
    println("WaKa".scww().addSC())//WaKa-帅次
    //Int类型15调用泛型扩展函数scww(),返回Int类型调用apply{}函数
    println(15.scww().apply { })//15
}
  • String类型WaKa调用泛型扩展函数scww()返回String类型调用String类型扩展函数addSC()

  • Int类型15调用泛型扩展函数scww()返回Int类型调用apply{}函数

        泛型扩展函数在Kotlin标准库里随处可见,例如apply函数,apply函数被定义成了泛型扩展函数,所以能支持任何类型。

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

三、扩展属性

        除了给类添加功能扩展函数外,你还可以给类定义扩展属性。

        扩展属性允许定义在类或者kotlin文件中,不允许定义在函数中。初始化属性因为属性没有后端字段(backing field),所以不允许被初始化只能由显式提供的 getter/setter 定义。

        扩展属性只能被声明为 val

//定义扩展属性
//给String类添加一个扩展属性,这个扩展属性可以统计字符长度并加10。
val String.lengthSc
    get() = this.length.plus(10)

//给School类添加个position属性
val School.position
    get() = "${name}-高级中学"
    
fun main() {    
    println("一二三四五,上山打老虎".lengthSc)//21
    println(School("新冠中学").position)//新冠中学-高级中学
}

四、可控类扩展

        你也可以定义扩展函数用于可空类型,在可空类型上定义扩展函数,你就可以直接在扩展函数体内解决可能出现的空值问题。

//可空类扩展
//当String为null时打印四大皆空-default
fun String?.nullWithDefault(default: String) {
    println(this ?: "四大皆空-$default")
}
//当School为null时,打印default-学校没了
fun School?.dropOut(default: String) {
    println(this ?: "$default-学校没了")
}

fun main() {
    var str: String? = null
    str.nullWithDefault("空空")//四大皆空-空空

    str = "数据已到"
    str.nullWithDefault("空空")//数据已到

    var school: School? = null
    school.dropOut("没得名字")//没得名字-学校没了

    school = School("帅次学院")
    school.dropOut("默认退学")//com.scc.kotlin.primary.extension.School@19dfb72a
}

infix 关键字

        infix关键字适用于有单个参数的扩展和类函数,可以让你以更简洁的语法调用函数,如果一个函数定义使用了infix关键字,那么调用它时,接收者和函数之间的点操作以及参数的一对括号都可以不要。 (类似 to 函数)

//infix关键字
infix fun String?.nullInfixDefault(default: String){
    println(this ?: "Infix-$default")
}
fun main() {
    str = null
    str nullInfixDefault "空值"   //Infix-空值
    str = "不空"
    str nullInfixDefault "空值"  //不空
    //这个就类似mapOf
    mapOf("Key" to "Value")
}

to函数源码

        泛型拓展函数、前面加了infix关键字

public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)

        Kotlin标准库中的扩展函数:Kotlin标准库提供的很多功能都是通过扩展函数和扩展属性来实现的,包含类扩展的标准库文件通常都是以类名加s后缀来命名的,例如Sequences.kt,Ranges.kt,Maps.kt。

五、定义扩展文件

        扩展函数需要在多个文件里面使用,可以将它定义在单独的文件,然后import。

5.1 定义扩展文件

package com.scc.kotlin.primary.extension

//定义扩展文件
fun <T> T.scFile(): T {
    println("来自ScFile的问候")
    return this
}

5.2 使用

        同一包名下的文件调用scFile():

fun main() {
    str.scFile()//来自ScFile的问候
}

        其他包下的文件调用scFile():

import com.scc.kotlin.primary.extension.scFile
fun main() {
    var userInfo4 = UserInfo4()
    userInfo4.scFile()//来自ScFile的问候
}

5.3 重命名扩展(import文件别名)

import com.scc.kotlin.primary.extension.scFile as scAliasFile

fun main() {
    var userInfo4 = UserInfo4()
    userInfo4.scAliasFile()//使用新定义的别名,来自ScFile的问候
//    userInfo4.scFile()//无法使用,报错
}

六、()->Unit 和 引用类型.()->Unit

package com.scc.kotlin.primary.extension

//() -> Unit:普通匿名函数
fun String.doAnonymous(anonymous:() -> Unit):String{
    anonymous()
    return "$this,AnonymousN"
}
//String.() -> Unit:匿名函数内部this指向一个String对象,隐式调用
fun String.doAnonymousString(anonymous: String.() -> Unit) :String{
    println(this)
    anonymous()
    return this
}
//这里使用的泛型匿名函数,使用其内部this
fun <T> T.doAnonymousT(anonymous: T.() -> Unit):T {
    println(this)
    anonymous()
    return this
}
fun main() {
    //普通匿名函数
    "a".doAnonymous{
//        println("$this,看看")//此处使用this,报错
    }

    //匿名函数内部this指向一个String对象
    "b".doAnonymousString{
        println("$this,看看")
    }
    15.doAnonymousT {
        println("$this,无敌是多么寂寞")
    }
}

DSL

        使用这样的编程范式,就可以写出业界知名的“领域特定语言”(DSL),一种API编程范式,暴露接收者的函数和特性,以便于使用你定义的lambda表达式来读取和配置它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Kotlin 初学者】扩展-享受编程 的相关文章

  • tomcat启动,报错Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]

    严重 RMI TCP Connection 3 127 0 0 1 org apache catalina core ContainerBase addChildInternal ContainerBase addChild start o
  • chrome扩展:manifest.json文件详解

    manifest json是扩展的配置文件 xff0c 指明了扩展的各种信息 一个manifest json格式如下 xff1a 必须的字段 3 个 34 name 34 34 MyExtension 34 扩展名称 34 version
  • 检测链表中是否存在回环(Java 版)

    检测链表中是否存在回环 xff0c 这里介绍两种方法 xff1a 快慢指针 xff1b HashSet 存储原理 xff1b 1 快慢指针 快慢指针检查 xff0c 就是定义两个指针 xff0c 一个走的快 xff0c 一个走的慢 xff0
  • 通过http接口进行批量post操作(json格式)

    通过 64 Test或者main方法来进行 相关依赖 poi lt dependency gt lt groupId gt org apache poi lt groupId gt lt artifactId gt poi lt artif
  • spring容器初始化bean后执行方法

    有时 xff0c 我们需要在启动bean时初始化bean属性 xff0c 例如读取perporties文件 xff0c 对属性进行赋值 xff1b 启动容器时让某个method方法执行等等 这时需要在进行配置 xff0c 让bean在注入时
  • 4个简单有效的网页视频下载方法,超级简单好用

    有很多网站的视频是没有下载功能的 xff0c 想要下载视频怎么办呢 xff1f 今天就分享给大家4个简单有效的网页视频下载方法 xff0c 多个平台都适用 xff0c 而且操作简单 xff0c 一看就会 xff01 一 审查元素下载 一个简
  • iptables详解

    5链 INPUT OUTPUT PREROUTING FORWARD POSTROUTING INPUT OUTPUT gt PREROUTING gt 是否为本机 gt FORWARD gt POSTROUTING gt 其他主机 所以
  • 浅谈一致性哈希算法 consistent hashing

    接触过分布式的小伙伴一定对一致性哈希算法这个词语不陌生 xff0c 那么到底什么是一致性哈希算法呢 xff1f 了解一致性哈希算法之前我们先了解下哈希取模 假设我们有三台服务器 xff0c 缓存3万张图片 当然我们可以均匀的分配到每个服务器
  • ubuntu20.04启用SSH

    新安装的ubuntu20 04默认是没有开启ssh的 xff0c 所以无法使用ssh登录系统 1 安装openssh server span class token function sudo span span class token f
  • 密码生成器

    import random def Range get num alist listout 61 while num gt 0 listout append alist random randint 0 len alist 1 num 61
  • centos7安装oracle中遇到的常见问题解决方法

    1 安装图形界面 yum y install gnome 2 安装vnc server yum y install vnc server vncpasswd 设置密码 vncserver启动vnc windows安装vnc客户端客户端 通过
  • java中keytool生成的jks证书转换为openssl格式证书

    一 通常jks文件包含了服务器的私钥 server key xff0c 服务器证书 server crt 根证书 ca crt 二 通过java的keytool工具导出成 PKCS12 格式文件 my p12 keytool importk
  • IBMX3650M4安装win2008Server操作指南

    IBMX3650M4安装win2008Server操作指南 由于IBM服务器是IBM原有的Linux系统 xff0c 所以需要在此硬件上安装Win 2008 Server系统 xff08 以下简称win8 xff09 xff0c 中间遇到了
  • windows远程桌面连接到服务器黑屏问题

    任务管理器使用组合键 Ctrl 43 Alt 43 End xff0c 于是打开了远程电脑的任务管理器 xff0c 取消 xff0c 即可返回桌面正常显示
  • p2p数据分析

    大数据在许多国家具有战略意义 xff0c 其原因不仅在少数巨头公司的应用 xff0c 而是大 中 小 微企业乃至个人 xff0c 都能利用大数据来创造新的价值 而互联网本身就是一个大数据的金矿 xff0c 利用它创造价值 xff0c 是时代
  • 关于The GPG keys listed for the "***" repository are already installed but they are not corret

    这个问题是在自己制作的repo源码库的时候出现的 xff0c 从字面上理解 xff0c 是 为 源码仓库出示的GPG密钥已经安装 xff0c 但不正确 首先 xff0c GPG密钥存在的目的是处于安全和规范考虑 xff0c RedHat在发
  • __stack_chk_fail问题分析

    一 问题 进程收到SIGABRT 信号异常退出 xff0c 异常调用栈显示 stack chk fail Build fingerprint 39 Pico A7H10 PICOA7H10 10 5 5 0 smartcm 16769120
  • 十套精美个人博客网站模板

    文件资源 点击下载 展示在下方 xff0c 点击你想下载的文件 xff0c 然后点击普通下载就能下载了 紫色的图片博客个人页面模板 红色的微博社交平台HTML模板 响应式生活博客设计网站HTML5模板 程序员个人博客模板 响应式的互联网IT
  • 高性能无锁环形队列 Disruptor

    Disruptor 环形队列 JLog 秒级百G级日志搜集 传输 存储解决方案 高性能无锁队列 Disruptor 高性能队列 Disruptor 使用教程 高性能队列Disruptor框架的详细说明与实战使用 SpringBoot 并发框
  • ubuntu20.04更换阿里的软件源

    新安装的ubuntu20 04的软件源是使用的国外的源 xff0c 因此在使用apt安装软件时速度并不怎么快 xff0c 建议大家更换为国内的源 xff0c 这样在使用apt安装软件时速度会有明显的提升的 ubuntu20 04 apt的配

随机推荐

  • mpi运行窗口无反应或者闪退

    原因有三 1 xff0c 服务未启动 2 xff0c 系统防火墙拦截
  • Newtonsoft.Json使用,C# Json文件读取,写入

    用学校作为例子 xff0c 有学校名称 xff0c 学校下面有班级 xff0c 班级有名字 xff0c 班级下面有学生 xff0c 这里面有数组 xff0c 有字段 using System using System Collections
  • Motrix全能下载工具使用

    Motrix是一款界面简约 功能丰富 专业可靠的全能下载工具 先下载 CSDN下载 Motrix zip下载 官方下载地址 Motrix 打开Motrix xff0c 将种子文件放到这里 开始下载
  • ActiveMQ-JMS(五):ObjectMessage的安全问题

    安全问题 按照apache官网的说明 xff0c 为了避免收到恶意代码 xff0c 引入了安全机制 xff0c 只允许指定的包里的对象能够被传输 原文如下 xff1a ObjectMessage objects depend on Java
  • 剑指offer 03

    span class token keyword class span span class token class name Solution span span class token punctuation span span cla
  • 「得印度者,得天下」聊聊你不知道的印度在线视频江湖

    印度 xff0c 一个神奇古老的国度 千百年来 xff0c 恒河水鉴证了古印度王朝的兴衰更迭 xff0c 壮丽的历史文化 xff0c 和印度文明缘起缘灭的生死轮回 时光飞转 xff0c 来到公元 2018年 恒河水波澜不惊一切如昨 xff0
  • Trinity简介(1)--用于无参考基因组的转录组de novo组装

    一 Trinity简介 Trinity xff0c 是由 the Broad Institute 开发的转录组de novo组装软件 xff0c 由三个独立的软件模块组成 xff1a Inchworm Chrysalis和Butterfly
  • Trinity进行转录组组装(2))

    1 Trinity进行转录组组装 Trinity进行转录组组装的典型命令如下 opt biosoft trinityrnaseq r20131110 Trinity pl seqType fq JM 50G left sample1 1 c
  • python的两种退出方式

    os exit vs sys exit 转自 xff1a http www cnblogs com gaott archive 2013 04 12 3016355 html 概述 python的程序有两种退出方式 xff1a os exi
  • R语言数据类型转化

    R语言数据类型转化 转自 xff1a http www wangluqing com 2014 09 10 r share34 有时候 xff0c 对于一些问题 xff0c 需要进行数据类型之间的转换 R提供了基本类型转换函数以解决数据类型
  • ubuntu20.04安装中文输入法

    虽然搜狗的官网已经宣传说已经支持2004 2010 xff0c 但是支持的并不完美 xff0c 闪退 xff0c 打不出字各种问题不断 xff0c 所以本文带领大家安装几款能够正常使用的中文输入法 但是正在我要发这篇博客的时候 xff0c
  • R语言做柱状图

    R语言做柱状图 转自 xff1a http www phperz com article 16 0102 180120 html 条形图代表在与条成比例的变量的值的长度矩形条数据 R使用函数barplot 来创建柱状图 R能够绘制柱状图垂直
  • R语言 PCA(主成分分析)

    R语言 PCA 转自 xff1a http www cnblogs com longzhongren p 4300593 html 1 关键点 综述 xff1a 主成分分析 因子分析 典型相关分析 xff0c 三种方法的共同点主要是用来对数
  • 使用Pandas对数据进行筛选和排序

    使用Pandas对数据进行筛选和排序 转自 xff1a http bluewhale cc 2016 08 06 use pandas filter and sort html 筛选和排序是Excel中使用频率最多的功能 xff0c 通过这
  • linux 下安装blat软件

    linux 下安装blat软件 blat是一款很经典的比对工具 xff0c 与blast相比 xff0c 具有速度快 共线性输出比对结果等优点 但是 xff0c blat源码包里面的README文件写得很不清楚 xff0c 这里 xff0c
  • 基于统计的压缩算法:游程编码

    原网址 xff1a http www cnblogs com xudong bupt p 3761417 html 基于统计的压缩算法 xff1a 游程编码 1 游程编码概念 游程编码又称 运行长度编码 或 行程编码 xff0c 是一种统计
  • BWT (Burrows–Wheeler_transform)数据转换算法

    原网址 xff1a https blog csdn net luanzheng 365 article details 78575429 BWT Burrows Wheeler transform 数据转换算法 1 什么是BWT 压缩技术主
  • pip使用豆瓣的镜像源

    抄自 xff1a https www cnblogs com ZhangRuoXu p 6370107 html pip使用豆瓣的镜像源 豆瓣镜像地址 xff1a https pypi douban com simple 虽然用easy i
  • PyVCF

    抄自 xff1a https www cnblogs com nkwy2012 p 9204088 html vcf文件的全称是variant call file xff0c 即突变识别文件 xff0c 它是基因组工作流程中产生的一种文件
  • 【Kotlin 初学者】扩展-享受编程

    作者简介 xff1a CSDN博客专家 华为云 云享专家认证 系列专栏 xff1a Kotlin 初学者 学习交流 xff1a 三人行必有我师焉 xff1b 择其善者而从之 xff0c 其不善者而改之 目录 一 介绍 二 扩展函数 2 1