Kotlin基础教程之Run,标签Label,函数Function-Type
作者:天命剑主 发布时间:2022-08-28 14:11:01
Kotlin基础教程之Run,标签Label,函数Function-Type
在Java中可以使用{}建立一个匿名的代码块,代码块会被正常的执行,除了改变了作用域之外,似乎并没有什么其他的作用。然而在Kotlin中却不能这么做,这是为什么呢?
其实,我们都知道一个函数一定与一个内存地址相关,而一个匿名的代码块其实也相当于是一个匿名的函数。在Kotlin中一般使用run函数来运行一段匿名代码块。
如下:
在Kotlin中使用标识符后跟@符号来定义一个标签,使用@后跟标识符来引用一个标签,run函数的语法初看起来似有一些怪异,其实run函数以一个函数作为参数,而一个匿名的代码块就可以是一个匿名函数,当我们在IntelliJ IDEA中把鼠标光标放到匿名代码块的大括号上时,会显示出匿名代码块对应的函数签名
local final fun <anonymous> ():Int defined in com.kotlin_learn.control_flow.fun_run
如图:
local代表作用域,定义在函数内部,作用域仅为local,final代表不可变,<anonymous>即为匿名,()是参数列表,Int是返回值,com.kotlin_learn.control_flow.fun_run是函数定义位置的完整路径。
由此可见,run函数的参数,那段匿名代码块被编译器转换为了一个匿名函数是毫无疑问的。
当然run函数是可以有返回值的,所以匿名代码块也可以是有返回值的匿名函数。
每一个函数都与一个或多个地址相对应,而每一个标签Label也是与一个或多个地址相对应,所以函数本身即是标签。
所以可以使用return@run之类的语法。
匿名函数虽然没有函数名,然而我们可以定义一个具名标签来代表这个函数,于是可以使用return@outer 2将2返回给i。
也许有人会有疑问,为什么不直接使用return 2呢,原因是return 将会从fun_run函数返回,而不是从匿名函数返回。
关于return和函数嵌套定义的问题下面还会说。
这段代码的运行结果如下:
接下来说一说forEach函数,与其他语言中不同,在Kotlin中forEach并不是一种语法,而是一类函数,forEach是iterator的函数,任何实现了iterator的类都可以使用forEach。forEach函数的参数也是一个函数,其参数是一个模板函数,可以是具名函数,匿名函数,lambda。forEach会对iterator迭代的每一个元素都调用一次传入的函数。
之所以讲到forEach,是为了熟悉标签的用法和return的用法。
如下:
别忘了infix function call。
运行结果如下:
接下来说一说function type,讨论一下函数。
对程序员来说,函数是很熟悉的,然而我们对函数就真的那么熟悉么?
函数也可以是类型,可以是变量,甚至常量。
如下:
在这段代码中我们定义了几个函数类型的变量和常量,并且在之间进行赋值等操作,其实和C++中的函数指针很相似,但是也有独特的地方。比如嵌套函数定义,函数标签的引用以及带标签的返回值等等。我们也看到了在一个匿名函数(end1代表的那个)中如何使用lambda表达式定义函数的参数列表和自动判断的返回类型。
这段代码运行结果如下:
刚才我们提到了函数嵌套定义,这是一个需要小心的地方。
看如下的代码:
从Java/C++一系出身的程序员(比如我:))很容易把这里的嵌套函数定义看成是匿名代码块的嵌套,以为程序会从外往内执行。从Pascal/PL一系出身的程序员就不会有这种问题,千万记住,函数虽然可以嵌套定义,但是如果没有调用是不会从外向内执行的。
所以输出很简单:
我们也看到了return的用法,这里的f1,f2,f3虽然是内部定义的函数,但是依然可以作为标签使用。
可见Kotlin是一种集大成的语言,甚至借鉴了古老的unix脚本和Pascal的语法,借鉴了很多语言的特性,再加上强大的编译器(Kotlin编译器会帮你做很多东西,远比其他语言做的多得多),使Kotlin的代码非常简洁优雅而且编程相当灵活高效。
在Kotlin中,太多的功能都是通过使用函数作为参数来实现,有的已经不能叫做语法,然而函数嵌套,infix function call,lambda,函数参数,可变参数列表,灵活的标签,强大的return,自动类型判断,Range,iterator,操作符重载,省略,模板...这些太多的功能,导致Kotlin的语法眼花缭乱,虽然有时看起来很优雅,但是也可能给人阅读代码带来巨大的困难。
最后以一段没什么卵用的代码结束本篇。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
来源:https://my.oschina.net/yuanhonglong/blog/469546


猜你喜欢
- zookeeper集群配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读
- 一个类,有时候搞不清楚到底用成员变量还是属性。 如: 成员变量 public string
- 上一篇Android中XUtils3框架使用方法详解(一)文章,主要介绍了XUtil3的注解模块,网络模块,图片加载模块,今天给大家带来数据
- public static void SortDicWithLinq(){ &nb
- 本文章牵涉到的技术点比较多:spring Data JPA、Redis、Spring MVC,Spirng Cache,所以在看这篇文章的时
- 需求描述 今日需求是删除资源时同时删除与该资源绑定的角色数据,有两张表,资源表、
- @MapperScan包扫描的坑在使用通用mapper执行查询时,由于不太注意顺手就导了spring的包:import org.mybati
- 本文实例讲述了C#保存listbox中数据到文本文件的方法。分享给大家供大家参考。具体实现方法如下:private void SaveLst
- bind函数定义在头文件 functional 中。可以将 bind 函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用
- 目录前言步入正题类的加载过程:1.加载2.验证3.准备4.解析5.初始化类加载器源码总结前言学生时代应抱着问题去学习一门语言,例如:在学习j
- 案例需求:访问带有验证码的登录页面login.jsp用户输入用户名,密码以及验证码。如果用户名和密码输入有误,跳转登录页面,提示:用户名或密
- 前言项目中时不时遇到查字典表等数据,只需要返回数据,不需要写其他业务,每个字典表可能都需要写一个接口给前端调用,比较麻烦,所以采用下面这种方
- 解压的工具类package com.example.videodemo.zip; public class ZipProgressUtil
- 1.流布局FlowLayout所有组件像流一样,一个一个排放,排满了一行之后排下一行,默认情况下,每个组件是居中排列的,但是也可以设置。流布
- 近来,很多公司的APP都实现了人脸识别登录的功能。今天呢,银鹏带大家从头到尾做一下这个人脸识别登录。首先呢,我们需要采用一个拥有人脸识别算法
- 在java中,static是一个修饰符,用于修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能;被static关键
- 前言在这一节为大家继续带来 Kotlin 中的一些高级的内容:Kotlin 中的 Kotlin 扩 展(Extensions)。Kotlin
- 不说废话了,进入我们今天的主题吧。先贴上前面内容的地址:Android手势ImageView三部曲(一)Android手势ImageView
- 本文实例讲述了Android编程实现下载图片及在手机中展示的方法。分享给大家供大家参考,具体如下:在项目开发中从互联网上下载图片是经常用到的
- 数据库中记录了商家在百度标注的经纬度(如:116.412007, 39.947545)最初想法,以圆心点为中心点,对半径做循环,半径每增加一