热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Kotlin——基础的函数/方法详解

对于Kotlin中的函数来说,和Javascript或者Lua这些语言很像,它有着这些语言的特性。但是也与这些语言就着许多不同之处。或许你更了解Java语言,然而对于Java语言来说,它不是不是闭包这

技术分享图片

对于Kotlin中的函数来说,和Javascript或者Lua这些语言很像,它有着这些语言的特性。但是也与这些语言就着许多不同之处。或许你更了解Java语言,然而对于Java语言来说,它不是不是闭包这个特性的。由于在这篇文章主要是讲解函数的基本使用,故而只会讲解到函数的定义函数的返回值函数的参数等。剩下的部分我会在这个系列的高级篇会给大家奉上。

目录

技术分享图片

一、函数的声明及基本使用


Kotlin中函数的声明,同Javascript相似。


1.1、函数的声明




  • Kotlin中的函数声明关键字为:fun

  • 定义格式为:可见性修饰符 fun 函数名(参数名 :类型,...) : 返回值{}


这里的可见性修饰符请参见我的另一篇文章Kotlin——可见性修饰符详解,至于返回值以及参数请继续往下面看

例:定义一个最基本的函数

fun basis(){
...
}

注意:



  • 上面的例子中没有可见性修饰符,那是因为Kotlin中默认为public可见性修饰符

  • ()圆括号必须存在,即使是没有参数的情况下

  • {}大括号必须存在,即使是没有函数体的时候,不过在Kotlin中有一个特例就是,函数具备返回值的时候,如果只用一个表达式就可以完成这个函数,则可以使用单表达式函数。在下面会详细的给大家讲解

  • 在函数没有返回值时可以省略其返回值



1.2、成员函数


成员函数是指在对象中的内部函数。你可以参见我的另一篇文章Kotlin——类详解

例:声明一个类,在类中在定义一个方法,这个方法就是这个类的成员函数

class Test{
fun foo(){}
}

1.3、函数的使用


函数的使用分为两种:


  • 普通的使用

  • 成员函数的使用


例:

// 普通的使用
basis()
// 如果函数有返回值
val x = basis()
// 成员函数的使用:先初始化对象,在根据对象使用`中缀符号(.)`调用其成员函数
Test().foo()
// 如果函数有返回值
val x = Test().foo()

二、函数的返回值


Kotlin中,函数的返回值类型可以分为:


  • Unit类型:该类型即无返回值的情况,可以省略。

  • 其他类型: 显示返回类型的情况



2.1、Unit类型




  • 这个类型可以理解为函数无返回值。


例:

fun unitFun() : Unit{
println("我是返回值为Unit的函数,Unit可省略")
return // return Unit 可省略
// 或者 return 可省略
}
等价于
fun unitFun(){
println("我是返回值为Unit的函数,Unit可省略")
}

当无返回值时,使用平时Java语法写普通函数一样即可。不需显示写成Unit。这里只是做一个介绍而已

2.2 、其他显示返回类型的返回值


这个类型可以理解为,该函数具有返回值,并且返回值类型不能省略,并且return也不能省略

例: 定义一个返回类型为Int的函数

fun returnFun() : Int{
return 2
}

三、函数的参数


对于函数中的参数来说,这里主要分为几个模块来讲解:


  • 具有参数的基本函数声明

  • 默认参数,即参数具有默认值

  • 命名参数,当传递参数的时候显示使用参数名 = 参数值

  • 可变数量的参数:即参数的个数不定。



3.1、具有参数的函数定义


定义一个具有参数的函数,使用Pascal表示法定义,即为:name : type。其中的参数必须具有显示的参数类型,并且参数与参数之间用逗号(,)隔开。

例:

fun funArgs(numA : Int, numB : Float){
println("numA = $numA \\t numB = $numB")
}
fun main(args: Array) {
funArgs(1,10f)
}

3.2、默认参数


对于默认参数,即使指一个函数中的参数具有默认值,这样在使用该函数的时候,可以省略一部分参数,可以减少函数的重载

例:定义个具有默认参数的函数

fun defArgs(numA : Int = 1, numB : Float = 2f, numC : Boolean = false){
println("numA = $numA \\t numB = $numB \\t numC = $numC")
}
fun main(args: Array) { // 默认参数的函数使用
defArgs()
defArgs(1,10f,true)
}

输出结果为:

numA = 1 numB = 2.0 numC = false
numA = 1 numB = 10.0 numC = true

可以看出:当具有默认参数时,可以对是参数有默认值的参数不传递参数值。

不过这里有一点值得注意的是: 当该函数是一个成员函数时,并且该函数时覆写继承类中的方法时,则该成员函数必须从签名中省略该函数的默认值。其实这一点不必过于看重,因为在你覆写方法时,编辑器都默认会帮你实现的..

举例说明:

open class A{
open fun foo(i : Int = 10){}
}
class B : A(){
override fun foo(i: Int) {
super.foo(i)
println(i)
}
}
fun main(args: Array) {
B().foo()
}

输出结果为:10

如果你对类继承不了解,可以参见我的另一篇文章Kotlin——面向对象的特征与类继承详解

3.3、命名参数


即在使用函数时显示使用参数名 = 参数值这种方式传递参数

例:这里举例一个普通的具有参数函数与具有默认参数函数的结合使用

fun callFun(str : String,
isTrue : Boolean = false,
numA : Int = 2,
numB: Float = 2.0f,
numC : Int = 2){}

可以看出,上面实例中的str参数是不具备默认值的。


  1. 我们可以这样使用它:

    callFun("str") // 这样是可以的,因为后面的参数都具有默认值


  2. 当使用非默认参数调用它时,使用起来就和Java函数一样:

    callFun("str",true,2,2.0,2) // 这样阅读性很差,因为你除了看函数的定义外,你不知道这些参数的含义


  3. 使用命名参数我们可以使代码更具有可读性:

    callFun("str",isTrue = true,numA = 3, numB = 3.0f, numC = 3)


  4. 当我们不需要所有的参数时:

    callFun("str",isTrue = true)


不过当我们使用命名参数时,虽然可以提高代码的阅读性,及在我们使用第34时有一个坑,就是Java中不支持这种写法的。而在实际的项目开发中,几乎上都是和Java语言混用的。那么这种用法就不适合了。所有这里还是推荐使用12两点的用法。这是只是介绍Kotlin的这种便利性而已。

3.4、可变数量参数




  • 当一个函数中的参数是不定数量的个数并且是同一个类型,则可是使用vararg修饰符去修饰这个变量,则被vararg修饰的参数相当于一个固定类型的数组。

  • 声明格式:fun 函数名(vararg 参数名 : 类型,...) :返回值{}


例:

fun varargFun(numA: Int, vararg str : String){
// ...
}

其中,既然vararg修饰的变量相当于一个固定类型的数组,则我们可以对它进行一些高级的操作。这里只举例一些简单的用法,如果你有兴趣,可以参见我的另一篇文章Kotlin——泛型之数组详解

例:

fun varargFun(numA: Int, vararg str : String){
// 遍历
for (s in str) {

}
// 获取元素
// str[index]
// str.component1() ... str.component5()
// 或者其高阶函数用法
// str.map { }
// str.filter { }
// str.sortBy { }
}

在传递参数值时,我们可以一个一个参数的传递,或者可以直接传递一个当前定义类型的数组。不过在传递数组时,请使用伸展操作符( * )

例:

普通传递 : varargFun(1,"aaa","bbb","ccc","ddd","fff")
数组传递:
val strArray = arrayOf("aaa","bbb","ccc","ddd","fff")
varargFun(1,*strArray)

四、单表达式函数




  • 上面提到了单表达式函数。这里详细的讲解一下。因为在结构体非常简单的情况下,使用单表达式函数还是能提高代码的阅读性的,并且可以少些两行代码。

  • 单表达式函数:即函数具备返回值的时候,可以省略花括号并且在=赋值符号之后指定代码体,而函数的返回值是有编辑器自动推断的。


例:

// 无参数的情况
fun test1() = 2 // 自动推断为:返回类型为Int
// 有参数的情况
fun test2(num : Int) = num * 2 // 自动推断为:返回类型为Int
// 或者
fun test3(x : Float, y : Int = 2) = x * y // 和默认参数一起使用,返回值为Float型
fun main(args: Array) {
println(test1())
println(test2(2))
println(test3(2f))
}

输出结果为:

2
4
4.0

总结

对于Kotlin中函数/方法的基本用法就讲解到这里,在后续的章节中,会为大家奉上函数的高级用法以及高阶函数的使用,并且会讲到其和lambda表达式的连用。
这一篇讲解的内容及其简单,如果您有编程经验您只要主要关注可变个数参数的函数,以及单表达式函数就可以额。

源代码

如果各位大佬看了之后感觉还阔以,就请各位大佬随便star一下,您的关注是我最大的动力。
我的个人博客:Jetictors
我的掘金:Jteictors
Github:Jteictors

欢迎各位大佬进群共同研究、探索

QQ群号:497071402
技术分享图片









推荐阅读
  • 全面解析JavaScript代码注释技巧与标准规范
    在Web前端开发中,JavaScript代码的可读性和维护性至关重要。本文将详细介绍如何有效地使用注释来提高代码的可读性,并探讨JavaScript代码注释的最佳实践和标准规范。通过合理的注释,开发者可以更好地理解和维护复杂的代码逻辑,提升团队协作效率。 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • 本文将继续探讨 JavaScript 函数式编程的高级技巧及其实际应用。通过一个具体的寻路算法示例,我们将深入分析如何利用函数式编程的思想解决复杂问题。示例中,节点之间的连线代表路径,连线上的数字表示两点间的距离。我们将详细讲解如何通过递归和高阶函数等技术实现高效的寻路算法。 ... [详细]
  • 在使用 SQL Server 时,连接故障是用户最常见的问题之一。通常,连接 SQL Server 的方法有两种:一种是通过 SQL Server 自带的客户端工具,例如 SQL Server Management Studio;另一种是通过第三方应用程序或开发工具进行连接。本文将详细分析导致连接故障的常见原因,并提供相应的解决策略,帮助用户有效排除连接问题。 ... [详细]
  • 本文介绍了如何在iOS平台上使用GLSL着色器将YV12格式的视频帧数据转换为RGB格式,并展示了转换后的图像效果。通过详细的技术实现步骤和代码示例,读者可以轻松掌握这一过程,适用于需要进行视频处理的应用开发。 ... [详细]
  • 在前文探讨了Spring如何为特定的bean选择合适的通知器后,本文将进一步深入分析Spring AOP框架中代理对象的生成机制。具体而言,我们将详细解析如何通过代理技术将通知器(Advisor)中包含的通知(Advice)应用到目标bean上,以实现切面编程的核心功能。 ... [详细]
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
  • 本文深入解析了Python在处理HTML过滤时的实现方法及其应用场景。通过具体实例,详细介绍了如何利用Python代码去除HTML字符串中的标签和其他无关信息,确保内容的纯净与安全。此外,文章还探讨了该技术在网页抓取、数据清洗等领域的实际应用,为开发者提供了宝贵的参考。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • 利用Python与Android进行高效移动应用开发
    通过结合Python和Android,可以实现高效的移动应用开发。首先,需要安装Scripting Layer for Android (SL4A),这是一个开源项目,旨在为Android系统提供脚本语言支持。SL4A不仅简化了开发流程,还允许开发者使用Python等高级语言编写脚本,从而提高开发效率和代码可维护性。此外,SL4A还支持多种其他脚本语言,进一步扩展了其应用范围。通过这种方式,开发者可以快速构建功能丰富的移动应用,同时保持较高的灵活性和可扩展性。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
author-avatar
Matherslll_493
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有