函数与变量

函数

一个普通的函数基本结构

语句和表达式
在kotlin中,if是表达式而不是语句。

语句和表达式的区别

表达式有值,并且能作为另一个表达式的一部分使用
而语句总是包围着它的代码块中的顶层元素,且没有自己的值

在java中所有的控制结构都是语句,在kotlin中除了循环(for while do/while)之外大多数控制结构都是表达式
另一方面,java中的赋值操作是表达式,在kotlin中却是语句

表达式函数体

可以让前面的函数变得更简单,因为它的函数体是由单个表达式构成的,可以用这个表达式作为完整的函数体,并去掉花括号的return语句

如果函数体写在花括号中,我们就说这个函数有代码块体。如果它返回了一个表达式,它就有表达式体。

继续简化,省略返回类型

对于表达式体函数来说,编译器会分析作为函数体的表达式,并把它的类型作为函数的返回类型,即使没有显式写出返回类型,这种分析叫做类型推导。
注意!只有表达式体函数的返回类型可以省略。对于有返回值的代码块体函数,必须显式写出返回类型和return语句。

变量

在java中声明变量时以类型开始,在kotlin中因为许多变量声明的类型都可以忽略,所以在kotlin中以关键字开始,然后是变量名称,最后可以加上类型(可选)

和表达式体函数一样,如果不指定变量的类型,编译器会分析初始化器表达式的值,并把它的类型作为变量的类型。在该例子中,变量的初始化器42(在这里42这个值是初始化器)的类型是Int,那么变量就是Int,如果使用浮点数常量,那么它就是Double类型

如果变量没有初始化器则需要显式指定它的类型

如果不能提供可以赋给这个变量的值的信息,编译器就无法推断出它的类型

可变变量和不可变变量

val

不可变引用。使用val声明的变量不能再初始化之后再次赋值,对应java的final变量

var

可变引用。值可以被改变,对应非final变量

默认情况下应尽可能用val关键字来声明所有的kotlin变量,仅在必要的时候换成var。
在定义了val变量的代码块执行期间,val变量只能进行唯一一次初始化,但如果编译器能确保只有唯一一条初始化语句会被执行,可根据条件使用不同的值来初始化它。

注意!尽管val引用自身是不可变的,但是它指向的对象可能是可变的

var关键字允许变量改变自己的值,但它的类型却是改变不了的

编译器只会根据初始化器来推断变量的类型,在决定类型的时候不会考虑后续的赋值操作

更简单的字符串格式化:字符串模板

如上图,kotlin可以让你在字符串字面值中引用局部变量,只需要在变量名称前加上字符$,表达式会进行静态检查,如果试着引用一个不存在的变量,代码不会编译。如果要在字符串中使用$,要使用转义字符\,
还可以引用更复杂的表达式,而不是仅限于简单的变量名称,只需要把表达式用花括号括起来。

类和属性

在kotlin中我们可以使用自动转换工具把java代码转换成kotlin代码

下图的Person即是我们要转换的对象

转换之后

这种只有数据没有其他代码的类通常被叫作值对象

在kotlin中public是默认的可见性,所以可以省略

属性

在java中,字段和其访问器的组合常常被叫作属性
在kotlin中,属性是头等的语言特性,完全替代了字段和访问器方法

基本上当你声明属性的时候你就声明了对应的访问器。访问器的默认实现非常简单,如果有需要可以自定义访问器。上图的类是一个字段都是私有的类,这些字段在构造方法中初始化并能通过对应的getter访问。这意味着在java和kotlin都能以同样方式使用这个类,不论它在哪里声明。

getter和setter的命名规则有一个例外,如果属性以is开头,getter不会增加任何前缀,setter会把is替换成set

在java中,使用person.setMarried(false)表示离婚
在kotlin中,可以写成person.isMarried=false

注意!
在java中定义的类一样可以使用kotlin的属性语法,java类中的getter可以被当成val属性在kotlin访问,而一对getter/setter可以被当成var属性访问。

自定义访问器

属性isSquare不需要字段来保存它的值,他只有一个自定义实现的hetter,它的值是每次访问属性的时候算出来的。
可以使用不带花括号的完整语法:get()=height==width 它们唯一的差异是可读性

kotlin的控制结构

枚举和when

声明枚举类

enum是一个软关键字:只有当它出现在calss前面时才有特殊的意义,在其他地方可以把它当成普通名称使用。和java一样,枚举不是值的列表:可以给枚举类声明属性和方法

如果要在枚举类中定义任何方法,就要使用分号把枚举常量列表和方法定义分开。

使用when处理枚举类

和if相似,when是一个有返回值的表达式,所以可以写一个直接返回when表示式的表达体式函数

不需要在每个分支都写上break语句,如果匹配成功,只有对应的分支会执行,也可以把多个值合并到同一个分支,只需要用逗号隔开这些值

当导入Color类后可以直接使用它们的名称

在when结构中使用任意对象

编译一个混合两种颜色的函数,举个例子

kotlin标准函数库中有一个setOf函数可以创建一个Set,他会包含所有指定为函数实参的对象。这种集合的条目顺序并不重要,只要两个set包含相同的条目那么它们就是一样的,如果没有其他的分支满足条件,else分支会执行,我们能使用任何表达式做when的分支条件

使用不带参数的when

上方的函数如果调用很频繁,他就只得用另一种方式重写来避免创建额外的垃圾对象

如果没有给when表达式提供参数,分支条件就是任意的布尔表达式,这样写的有点事不会创建额外的对象,缺点是更难理解

智能转换:合并类型检查和转换

编写一个函数对如(1+2)+4这样的算术表达式求值,我们可以把它们存储在一个树状结构中,书中的每个节点要么是一次求和要么是一个数字,Num永远是叶子节点,而Sum节点有两个子节点,他们是求和的两个参数。下图为示例

Expr接口

Num类是一个简单的值对象,只有一个属性value并实现了Expr接口

Sum运算的实参可以是任何Expr,也就是Num或者Sum

eval

在kotlin要用is检查一个变量是否属于某种类型。在java中,如果你已经检查过一个变量是某种类型并且要把它当作这种类型来访问其成员时,在检查之后还需要显式加上类型转换。如果最初的变量会使用超过一次,常常选择把类型转换的结果存储在另一个单独的变量里。而在kotlin中,编译器帮你完成了这些工作,如果你检查过一个变量是某种类型,后面就不再需要转换它,可以就把它当作你检查过的类型使用,事实上编译器为你执行了类型转换,这种行为称为类型转换

在我们编写的eval函数中,在检查过e是否为Num类型后,编译器就把它当成Num类型的变量解释。智能转换只在变量经过is检查且之后不再发生变化的情况下有效。当你对一个类的属性进行智能转换的时候,这个属性必须是一个val属性,而且不能有自定义访问器。否则每次对属性的访问是否都能返回同样的值将无从验证

as关键字来表示到特定类型的显式转换

重构eval函数使其更符合kotlin风格

如果分支只有一个表达式,花括号是可以省略的。如果if分支是一个代码块,代码块中的最后一个表达式会被作为结果返回

继续重写

代码块作为if和when的分支

if和when都可以使用代码块作为分支体,这种情况下代码块最后一个表达式就是结果

规则
代码块中最后的表达式就是结果,在所有使用代码块并期望得到一个结果的地方成立。但这个规则对常规函数不成立。一个函数要么具有不是代码块的表达式函数体,要么是具有包含显式return的代码块函数体

while循环和for循环

kotlin有while和dowhile循环,语法和java中没什么不同

在kotlin中没有常规的java的for循环,kotlin使用了区间概念。区间本质上就是两个值之间的间隔,这两个值通常是数字:一个起始值,一个结束值,用…运算符来表示区间

注意kotlin的区间是包含的或者闭合的,意味着第二个值始终是区间的一部分
整数区间能做的最基本事情就是循环迭代器中所有的值。如果你能迭代区间中所有的值,这样的区间被称为数列

例子

结果

修改循环条件:从100开始,把步长改为2,数到1为止

结果部分截图

许多情况下迭代不包含指定结束值的半闭合区间更方便。使用until函数可以创建这样的区间。如for(x in 0 until size)等同于for(x in 0…size-1)

迭代map

结果

…语法不仅可以创建数字区间,还可创建字符区间。上图展示了for循环允许展开迭代中的集合的元素(在这里展开的是map的键值对集合),把展开的结果存储到了两个独立的变量中。而且访问和更新map不需要依靠get和set函数。

可以用这样的展开语法在迭代集合的同时跟踪当前项的下标,不需要创建一个单独的变量来存储下标并手动增加它

结果

使用in检查集合和区间的成员

检查一个字符是否是字母

in和!in运算符也适用于when表达式

用in检查作为when分支

区间也不仅限于字符。假如有一个支持实例比较操作的任意类(实现了Comparable接口),就能创建这种类型的对象的区间。

试想是否可以列举出"java"和"kotlin"之间所有字符串,答案是不能,但是仍然可以使用in运算符检查一个其他的对象是否属于这个区间

in检查同样适用于集合

kotlin中的异常

异常处理语句的基本形式和java类似,抛出异常的方式也不例外。和java不同的是,kotlin中throw结构是一个表达式,能作为另一个表达式的一部分使用

try-catch-finally语句

和java最大区别就是throws没有出现在代码中,因为kotlin并不区分受检异常和未受检异常。不用指定函数抛出的异常,而且可以处理也可以不处理异常

try作为表达式

try和if、when一样引入了一个表达式,可以把它的值赋给一个变量。不同于if,你总是需要用花括号把语句主主体括起来。和其他语句一样如果其主体包含多个表达式,那么整个try表达式的值就是最后一个表达式的值,该函数执行到catch便会停止,如果你想继续执行,catch子句也需要有一个值,它将是子句中最后一个表达式的值

【Kotlin学习】Kotlin基础知识相关推荐

  1. python语言的单行注释以井号开头_推荐|零基础学习Python基础知识

    原标题:推荐|零基础学习Python基础知识 Python是一种面向对象.解释型计算机程序设计语言.语法简洁清晰,强制用空白符作为语句缩进. Python具有丰富和强大的库,又被称为胶水语言.能把其他 ...

  2. Hadoop学习笔记—15.HBase框架学习(基础知识篇)

    Hadoop学习笔记-15.HBase框架学习(基础知识篇) HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase ...

  3. 关于图计算图学习的基础知识概览:前置知识点学习(PGL)[系列一]

    关于图计算&图学习的基础知识概览:前置知识点学习(Paddle Graph Learning (PGL)) 0.1图计算基本概念 首先看到百度百科定义: 图计算(Graph Processin ...

  4. 快速学习mysql_快速学习MySQL基础知识

    这篇文章主要梳理了 SQL 的基础用法,会涉及到以下方面内容: SQL大小写的规范 数据库的类型以及适用场景 SELECT 的执行过程 WHERE 使用规范 MySQL 中常见函数 子查询分类 如何选 ...

  5. 三 计算机知识的重要性分析,学习计算机基础知识对中专学生的重要性分析

    学习计算机基础知识对中专学生的重要性分析 [摘 要]本文主要介绍了计算机基础知识的内容,阐述了学习计算机基础知识对中专学生的作用,并且通过对计算机基础操作的学习,提高中专学生的计算机应用水平.希望本文 ...

  6. 谈计算机知识对学生的作用,浅谈学习计算机基础知识对中专学生的重要性

    [摘 要]本文主要介绍了计算机基础知识的内容,阐述了学习计算机基础知识对中专学生的作用,并且通过对计算机基础操作的学习,提高中专学生的计算机应用水平.希望本文可以让中专学生认识到学习计算机基础知识的重 ...

  7. 《机器学习》理论——速读学习1 基础知识

    <机器学习>理论--速读学习1 基础知识 该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动! Time: 2021-12-05 学习目标:我需要了解神经网络除了工程 ...

  8. A.关于图计算图学习的基础知识概览:前置知识点学习(Paddle Graph L)【一】

    图学习图神经网络算法专栏简介:主要实现图游走模型(DeepWalk.node2vec):图神经网络算法(GCN.GAT.GraphSage),部分进阶 GNN 模型(UniMP标签传播.ERNIESa ...

  9. 直播平台怎么搭建,你要先来学习音频基础知识

    直播平台怎么搭建,你要先来学习音频基础知识 概述 本片文章主要介绍音频基础,在做音频开发之前首先必须要对音频的相关概念了解.以下是具体内容概述: 常见的音频格式 WAV MP3 WMA RA APE ...

  10. 学习编程基础知识,进阶成为更优秀的程序员

    "脚本小子"常常从某些网站上复制脚本代码,然后到处粘贴,却并不明白其中的方法与原理 ​​当你看到编程语言编进教材的时候,看到一个文科生也在编写Python程序进行数据分析的时候,你 ...

最新文章

  1. Repeater 使用小技巧 内部radio 横排
  2. 启动器中图标的默认路径
  3. 十分钟搞定JeecgBoot 单体升级微服务!
  4. 做游戏,学编程(C语言) 10 僵尸危机
  5. Python socket编程模拟最简单的HTTP响应
  6. select和epoll
  7. Stubs和Mocks区别 (Stubs vs. Mocks)
  8. 华为云服务查找手机_华为云服务登录入口
  9. maven中filtering的使用
  10. iphoneX适配-客户端H5页面
  11. BDCN:Bi-Directional Cascade Network for Perceptual Edge Detection论文解读和代码实现
  12. C语言心语,心语,心缘
  13. html在360浏览器如何修改字体大小,360浏览器网页中字体大小如何修改
  14. 炫酷可视化教程 Cufflinks 来啦!!!
  15. linux中ifconfig无法显示ip地址
  16. Vue编译处理: warning Delete `␍` prettier/prettier
  17. 动态规划题集(转载)
  18. c语言指针b 和b j,c语言精华 ------ 指针和数组
  19. 远程连接自动断开的问题解决办法 screen
  20. OpenCore的编译

热门文章

  1. 共享池 shared pool
  2. BAD_POOL_CALLER蓝屏故障
  3. 【搜索引擎基础】spider
  4. 设置计算机电源方案20分钟后,屏保为什么我的电脑在20分左右不操作会自动 – 手机爱问...
  5. 压力机性能瓶颈分析及优化
  6. IE7下li Bug
  7. 千兆网卡和普通网卡有什么区别?如何判断?
  8. 如何对一个顶级域名设置域名解析
  9. 7-11 Say Hello to Integers
  10. Line披露母公司Naver详情:去年营收28.4亿美元