kotlin 知识点一 变量和函数

在Kotlin中定义变量的方式和Java 区别很大,在Java 中如果想要定义一个变

量,需要在变量前面声明这个变量的类型,比如说int a表示a是一个整型变量,String b表

示b是一个字符串变量。而Kotlin中定义一个变量,只允许在变量前声明两种关键字:val和

var。

val(value 的简写)用来声明一个不可变的变量,这种变量在初始赋值之后就再也不能重新赋

值,对应Java 中的final变量。

var(variable 的简写)用来声明一个可变的变量,这种变量在初始赋值之后仍然可以再被重新

赋值,对应Java 中的非final变量。

如果你有Java 编程经验的话,可能会在这里产生疑惑,仅仅使用val或者var来声明一个变量,

那么编译器怎么能知道这个变量是什么类型呢?这也是Kotlin比较有特色的一点,它拥有出色的

类型推导机制。

举个例子,我们打开上一节创建的LearnKotlin 文件,在main()函数中编写如下代码:

复制代码
fun main() { 
 val a = 10 
 println("a = " + a) 
}

注意,Kotlin每一行代码的结尾是不用加分号的,如果你写惯了Java 的话,在这里得先熟悉一

下。

在上述代码中,我们使用val关键字定义了一个变量a,并将它赋值为10 ,这里a就会被自动推

导成整型变量。因为既然你要把一个整数赋值给a,那么a就只能是整型变量,而如果你要把一

个字符串赋值给a的话,那么a就会被自动推导成字符串变量,这就是Kotlin的类型推导机制。

现在我们运行一下main()函数,执行结果如图所示,正是我们所预期的。

但是Kotlin的类型推导机制并不总是可以正常工作的,比如说如果我们对一个变量延迟赋值的

话,Kotlin就无法自动推导它的类型了。这时候就需要显式地声明变量类型才行,Kotlin提供了

对这一功能的支持,语法如下所示:

复制代码
val a: Int = 10 

可以看到,我们显式地声明了变量a为Int类型,此时Kotlin就不会再尝试进行类型推导了。如

果现在你尝试将一个字符串赋值给a,那么编译器就会抛出类型不匹配的异常。

如果你学过Java 并且足够细心的话,你可能发现了Kotlin中Int的首字母是大写的,而Java 中

int的首字母是小写的。不要小看这一个字母大小写的差距,这表示Kotlin完全抛弃了Java 中的

基本数据类型,全部使用了对象数据类型。在Java 中int是关键字,而在Kotlin中Int变成了一

个类,它拥有自己的方法和继承结构。

表中列出了Java 中的每一个基本数据类型在Kotlin中对应的对象数据类型。

接下来我们尝试对变量a进行一些数学运算,比如说让a变大10 倍,可能你会很自然地写出如下

代码:

复制代码
fun main() { 
 val a: Int = 10 
 a = a * 10 
 println("a = " + a) 
}

很遗憾,如果你这样写的话,编译器一定会提示一个错误:Val cannot be reassigned 。这是

在告诉我们,使用val关键字声明的变量无法被重新赋值。出现这个问题的原因是我们在一开始

定义a的时候将它赋值成了10 ,然后又在下一行让它变大10 倍,这个时候就是对a进行重新赋值

了,因而编译器也就报错了。

解决这个问题的办法也很简单,前面已经提到了,val关键字用来声明一个不可变的变量,而

var关键字用来声明一个可变的变量,所以这里只需要把val改成var即可,如下所示:

复制代码
fun main() { 
 var a: Int = 10 
 a = a * 10 
 println("a = " + a) 
}

现在编译器就不会再报错了,重新运行一下代码

可以看到,a的值变成了100 ,这说明我们的数学运算操作成功了。

这里你可能会产生疑惑:既然val关键字有这么多的束缚,为什么还要用这个关键字呢?干脆全

部用var关键字不就好了。其实Kotlin之所以这样设计,是为了解决Java 中final关键字没有被

合理使用的问题。

在Java 中,除非你主动在变量前声明了final关键字,否则这个变量就是可变的。然而这并不

是一件好事,当项目变得越来越复杂,参与开发的人越来越多时,你永远不知道一个可变的变

量会在什么时候被谁给修改了,即使它原本不应该被修改,这就经常会导致出现一些很难排查

的问题。因此,一个好的编程习惯是,除非一个变量明确允许被修改,否则都应该给它加上

final关键字。

但是,不是每个人都能养成这种良好的编程习惯。我相信至少有90% 的Java 程序员没有主动在

变量前加上final关键字的意识,仅仅因为Java 对此是不强制的。因此,Kotlin在设计的时候就

采用了和Java 完全不同的方式,提供了val和var这两个关键字,必须由开发者主动声明该变量

是可变的还是不可变的。

那么我们应该什么时候使用val,什么时候使用var呢?这里我告诉你一个小诀窍,就是永远优

先使用val来声明一个变量,而当val没有办法满足你的需求时再使用var。这样设计出来的程

序会更加健壮,也更加符合高质量的编码规范。

函数

对于函数和方法这两个概念有些混淆,不明白它们有什么区别。其实,函

数和方法就是同一个概念,这两种叫法都是从英文翻译过来的,函数翻译自function ,方法翻

译自method ,它们并没有什么区别,只是不同语言的叫法习惯不一样而已。而因为Java 中方

法的叫法更普遍一些,Kotlin中函数的叫法更普遍一些,因此本书里可能会交叉使用两种叫法,

你只要知道它们是同一种东西就可以了,不用在这个地方产生疑惑。

函数是用来运行代码的载体,你可以在一个函数里编写很多行代码,当运行这个函数时,函数

中的所有代码会全部运行。像我们前面使用过的main()函数就是一个函数,只不过它比较特

殊,是程序的入口函数,即程序一旦运行,就是从main()函数开始执行的。

但是只有一个main()函数的程序显然是很初级的,和其他编程语言一样,Kotlin也允许我们自

由地定义函数,语法规则如下:

复制代码
fun methodName(param1: Int, param2: Int): Int { 
 return 0 
}

下面我来解释一下上述的语法规则,首先fun(function 的简写)是定义函数的关键字,无论你

定义什么函数,都一定要使用fun来声明。

紧跟在fun后面的是函数名,这个就没有什么要求了,你可以根据自己的喜好起任何名字,但是

良好的编程习惯是函数名最好要有一定的意义,能表达这个函数的作用是什么。

函数名后面紧跟着一对括号,里面可以声明该函数接收什么参数,参数的数量可以是任意多

个,例如上述示例就表示该函数接收两个Int类型的参数。参数的声明格式是"参数名: 参数类

型",其中参数名也是可以随便定义的,这一点和函数名类似。如果不想接收任何参数,那么写

一对空括号就可以了。

参数括号后面的那部分是可选的,用于声明该函数会返回什么类型的数据,上述示例就表示该

函数会返回一个Int类型的数据。如果你的函数不需要返回任何数据,这部分可以直接不写。

最后两个大括号之间的内容就是函数体了,我们可以在这里编写一个函数的具体逻辑。由于上

述示例中声明了该函数会返回一个Int类型的数据,因此在函数体中我们简单地返回了一个0。

这就是定义一个函数最标准的方式了,虽然Kotlin中还有许多其他修饰函数的关键字,但是只要

掌握了上述函数定义规则,你就已经能应对80% 以上的编程场景了,至于其他的关键字,我们

会在后面慢慢学习。

接下来我们尝试按照上述定义函数的语法规则来定义一个有意义的函数,如下所示:

复制代码
fun largerNumber(num1: Int, num2: Int): Int { 
 return max(num1, num2) 
}

这里定义了一个名叫largerNumber()的函数,该函数的作用很简单,接收两个整型参数,然

后总是返回两个参数中更大的那个数。

注意,上述代码中使用了一个max()函数,这是Kotlin提供的一个内置函数,它的作用就是返回

两个参数中更大的那个数,因此我们的largerNumber()函数其实就是对max()函数做了一层

封装而已。

现在你可以开始在LearnKotlin 文件中实现largerNumber()这个函数了,当你输入"max" 这

个单词时,Android Studio 会自动弹出如图

Android Studio 拥有非常智能的代码提示和补全功能,通常你只需要键入部分代码,它就能自

动预测你想要编写的内容,并给出相应的提示列表。我们可以通过上下键在提示列表中移动,

然后按下"Enter" 键,Android Studio 就会自动帮我们进行代码补全了。

这里我非常建议你经常使用Android Studio 的代码补全功能,可能有些人觉得全部手敲更有成

就感,但是我要提醒一句,使用代码补全功能后,Android Studio 不仅会帮我们补全代码,还

会帮我们自动导包,这一点是很重要的。比如说上述的max()函数,如果你全部手敲出来,那

么这个函数一定会提示一个红色的错误,如图

max()函数提示错误

出现这个错误的原因是你没有导入max()函数的包。当然,导包的方法也有很多种,你将光标

移动到这个红色的错误上面就能看到导包的快捷键提示,但是最好的做法就是使用Android

Studio 的代码补全功能,这样导包工作就自动完成了。

现在我们使用代码补全功能再来编写一次max()函数,你会发现LearnKotlin 文件的头部自动导

入了一个max()函数的包,并且不会再有错误提示了,如图

相关推荐
<但凡.2 分钟前
C++修炼:红黑树的模拟实现
开发语言·数据结构·c++·算法
友莘居士13 分钟前
创建信任所有证书的HttpClient:Java 实现 HTTPS 接口调用,等效于curl -k
java·开发语言·https·httpclient·curl -k
君的名字17 分钟前
怎么判断一个Android APP使用了React Native 这个跨端框架
android·react native·react.js
coding随想38 分钟前
JavaScript的三大核心组成:ECMAScript、DOM与BOM
开发语言·javascript·ecmascript
0xCC说逆向1 小时前
Windows逆向工程提升之IMAGE_EXPORT_DIRECTORY
开发语言·数据结构·windows·安全·网络安全·pe结构·逆向工程
带电的小王1 小时前
C++:动态刷新打印内容
开发语言·c++
贺函不是涵1 小时前
【沉浸式求职学习day47】【JSP详解】
java·开发语言·学习
满怀10151 小时前
【Python正则表达式终极指南】从零到工程级实战
开发语言·python·正则表达式·自动化·文本处理·数据清晰
君的名字1 小时前
怎么判断一个Android APP使用了Electron 这个跨端框架
android·javascript·electron
草莓熊Lotso1 小时前
【自定义类型-结构体】--结构体类型,结构体变量的创建和初始化,结构体内存对齐,结构体传参,结构体实现位段
c语言·开发语言·经验分享·笔记·其他