Kotlin系列之顶层函数、中缀调用、解构声明

本文深入探讨Kotlin的顶层函数,解释为何它们优于Java的静态函数,并展示其基本使用和原理。同时,文章介绍了中缀调用的语法糖和解构声明,包括它们的原理、注意事项和实际应用。通过对Kotlin的这些特性理解,开发者可以写出更简洁、高效的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简述: 今天带来的是Kotlin浅谈系列的第四弹,这次主要聊下Kotlin独有的新特性,Java不具备的。Kotlin是一种增加许多新功能的语言,允许编写更简洁易读的代码,这使得我们的代码更易于维护。例如使用顶层函数和属性从此消除Java中的static、中缀表达式调用和解构声明等。

  • 1、为什么要用顶层函数替代Java中的static函数
  • 2、顶层函数和属性的基本使用
  • 3、顶层函数实质原理
  • 4、顶层函数使用应注意哪些问题
  • 5、一起尝尝中缀调用语法糖
  • 6、中缀调用的基本使用
  • 7、中缀调用实质原理
  • 8、中缀调用应注意哪些问题
  • 9、Kotlin中的解构声明

一、为什么要用顶层函数替代Java中的static函数

概念: 我们知道在Java中有静态函数和静态属性概念,它们一般作用就是为了提供一个全局共享访问区域和方法。我们一般的习惯的写法就是写一个类包裹一些static修饰的方法,然后在外部访问的直接利用类名.方法名访问。

问题: 我们都知道静态函数内部是不包含状态的,也就是所谓的纯函数,它的输入仅仅来自于它的参数列表,而它的输出也仅仅依赖于它参数列表。我们设想一下这样开发情景,有时候我们并不想利用实例对象来调用函数,所以我们一般会往静态函数容器类中添加静态函数,如此反复,这样无疑是让这个类容器膨胀。

解决: 在Kotlin中则认为一个函数或方法有时候并不是属于任何一个类,它可以独立存在。所以在Kotlin中类似静态函数和静态属性会去掉外层类的容器,一个函数或者属性可以直接定义在一个Kotlin文件的顶层中,在使用的地方只需要import这个函数或属性即可。如果你的代码还存在很多以"Util"后缀结尾的工具类,是时候去掉了。

二、顶层函数和属性的基本使用

在Koltin中根本不需要去定义一些没有意义包裹静态函数的容器类,它们都被顶层文件给替代。我们只需要定义一个Kotlin File,在里面定义好一些函数(注意: 不需要static关键字)。那么这些函数就可以当做静态函数来使用

创建一个顶层文件:

在顶层文件中定义一个函数:

package com.mikyou.kotlin.top

import java.math.BigDecimal

/**
 * Created by mikyou on 2018/4/10.
 */
//这个顶层函数不属于任何一个类,不需要类容器,不需要static关键字
fun formateFileSize(size: Double): String {
   
   
    if (size < 0) {
   
   
        return "0 KB"
    }

    val kBSize = size / 1024
    if (kBSize < 1) {
   
   
        return "$size B"
    }

    val mBSize = kBSize / 1024
    if (mBSize < 1) {
   
   
        return "${
     
     BigDecimal(kBSize.toString()).setScale(1, BigDecimal.ROUND_HALF_UP).toPlainString()} KB"
    }

    val mGSize = mBSize / 1024
    if (mGSize < 1) {
   
   
        return "${
     
     BigDecimal(mBSize.toString()).setScale(1, BigDecimal.ROUND_HALF_UP).toPlainString()} MB"
    }

    val mTSize = mGSize / 1024
    if (mTSize < 1) {
   
   
        return "${
     
     BigDecimal(mGSize.toString()).setScale(1, BigDecimal.ROUND_HALF_UP).toPlainString()} GB"
    }
    return "${
     
     BigDecimal(mTSize.toString()).setScale(1, BigDecimal.ROUND_HALF_UP).toPlainString()} TB"
}

//测试顶层函数,实际上Kotlin中main函数和Java不一样,它可以不存在任何类容器中,可以直接定义在一个Kotlin 文件中
//另一方面也解释了Kotlin中的main函数不需要了static关键字,实际上它自己就是个顶层函数。
fun main(args: Array<String>) {
   
   
    println("文件大小: ${
     
     formateFileSize(15582.0)}")
}

从以上代码可以看出定义一个顶层函数是不是很简单,那么问题来了这个formateFileSize函数定义在一个文件内部,在JVM中是怎么执行的呢?请接着往下看…

三、顶层函数实质原理

通过以上例子我们思考一下顶层函数在JVM中是怎么运行的,如果你仅仅是在Kotlin中使用这些顶层函数,那么可以不用细究。但是如果你是Java和Kotlin混合开发模式,那么你就有必要深入内部原理。我们都知道Kotlin和Java互操作性是很强的,所以就衍生出了一个问题:在Kotlin中定义的顶层函数,在Java可以调用吗?答案肯定是可以的。怎么调用的,请接着看。

要想知道内部调用原理很简单,我们只需要把上面例子代码反编译成Java代码就一目了然了。这里科普一下反编译Kotlin代码步骤,因为这是查看Kotlin语法糖背后实质很好的方法。

步骤一: 确认IDE安装好了Kotlin Plugin

步骤二: 在IDE中打开你需要查看反编译的代码文件,然后打开顶部的"Tools",选择"Kotlin",再选择"Show Kotlin ByteCode"

步骤三: 左边是Kotlin的源码,右边是Kotlin的ByteCode

步骤四: 点击右侧“Decompile”

package com.mikyou.kotlin.top;

import java.math.BigDecimal;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {
   
   1, 1, 9},
   bv = {
   
   1, 0, 2},
   k = 2,
   d1 = {
   
   "\u0000\u001c\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\u0006\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n\u0002\b\u0002\u001a\u000e\u0010\u0000\u001a\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u0003\u001a\u0019\u0010\u0004\u001a\u00020\u00052\f\u0010\u0006\u001a\b\u0012\u0004\u0012\u00020\u00010\u0007¢\u0006\u0002\u0010\b¨\u0006\t"},
   d2 = {
   
   "formateFileSize", "", "size", "", "main", "", "args", "", "([Ljava/lang/String;)V", "production sources for module Function"}
)
public final class TopExtFileFormatKt {
   
   //一般以文件名+"Kt"后缀作为容器类名
   @NotNull
   public static final String formateFileSize(double size) {
   
   //顶层函数反编译成Java中静态函数
      if(size < (double)0) {
   
   
         return "0 KB";
      } else {
   
   
         double kBSize = size / (double)1024;
         if(kBSize < (double)1) {
   
   
            return "" + size + " B";
         } else {
   
   
            double mBSize = kBSize / (double)1024;
            if(mBSize < (double)1) {
   
   
               return "" + (new BigDecimal(String.valueOf(kBSize))).setScale(1, 4).toPlainString() + " KB";
            } else {
   
   
               double mGSize = mBSize / (double)1024;
               if(mGSize < (double)1) {
   
   
                  return "" + (new BigDecimal(String.valueOf(mBSize)))
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊喵先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值