2.1、基本要素:函数和变量
1、函数
-
举例说明
-
HelloWrold.kt
-
fun main(args: Array<String>) { println("hello world!") }
-
-
分析
- 1、关键字 fun 用来声明 一个函数
- 2、参数的类型写在它的名称后面
- 3、函数可以定义在文件的最外层,不需要把它放在类中
- 4、数组就是类(和 Java不同,Kotlin没有声明数组类型的特殊语法)
- 5、使用 println代替了 System.out.println。Kotlin标准库给 Java标 准库函数提供了许多语法更简洁的包装,而 println 就是其中 一个
- 6、和许多其他现代语言一样,可以省略每行代码结尾的分号
-
-
函数结构
- 1、函数的声明以fun关键字开始;
- 2、函数名称紧随其后;
- 3、括号里面是参数列表(先写参数变量名,接着写后参数所属类型,用冒号分开);
- 4、参数列表后面是返回类型,用冒号分开
-
表达式函数体
-
可以让前面的函数变得更简单,因为它的函数体是由单个表达式构成的,可以用这个表达式作为完整的函数体,具体操作:
- 1、去掉花括号和 return 语句;
- 2、改为等号;
- 3、去掉返回类型
HTML学习的本质就是该是什么就用什么
-
代码
fun max2(a: Int, b: Int): Int = if (a > b) a else b
-
如果函数体写在花括号中,我们说这个函数有代码块体,如果它直接返回了 一个表达式,它就有表达式体
-
进一步简化,去掉返回类型
fun max3(a: Int, b: Int) = if (a > b) a else b
为什么可以去掉返回类型?
-
每一个表达式和变量都有类型
-
每个函数都有返回类型
-
对于表达式体函数来说,编译器会分析作为函数体的表达式,并把它的类型作为函数的返回类型,即使没有显示的写出来,这种分析通常被称作类型推导
-
表达式函数体小结
- 使用范围:单个表达式
- 使用场景
- 简单的单行函数中
- 对更复杂的单个表达式求值的函数中
-
-
2、变量
-
Kotlin鼓励你使用不可变的数据,而不是可变的数据
-
java中声明变量是以类型开始,但是kotlin中许多变量声明的类型可以省略,所以:
- 1、kotlin中变量的声明是从关键字开始,
- 2、然后是变量名称,
- 3、最后加上类型(如果变量没有初始化,需要显示地指定它的类型),
- 4、再加上变量的初始值(val变量要初始化)
-
不可变变量val
-
只能初始化一次
-
val answer: Int = 42
-
如果编译器能确保只有唯一一条初始化语句会被执行,可以根据条件使用不同的值来初始化它
val message: String if(canPerformOperation()){ message = "Success" }else{ message = "Failed" }
-
尽管 val 引用自身是不可变的,但是它指向的对象可能是可变的。例如,下面这段代码是完全有效的
//声明不可变引用 val languages= arrayListOf("Java") //改变引用指向的对象 languages.add("Kotlin")
-
-
-
可变变量var
-
变量值可以多次改变
- 即使var关键字允许变量改变自己的值,但它的类型却是改变不了的
-
3、更简单的字符串格式化:字符串模板
-
代码
-
val name = if (args.size > 0) args[0] else "Kotlin" println("hello $name") //打印$,对$进行转义 println("hello \$name") //复杂表达式 println("hello ,${ args[0]}") //嵌套双引号 println("hello,${ if(args.size>0) args[0] else "Love Kotlin"}")
-
4、语句和表达式
-
在Kotlin中,if是表达式,而不是语句
-
表达式和语句的区别
- 表达式有值,能作为另一个表达式的一部分使用
- 语句是包围着它的代码块中的顶层元素,没有自己的值
-
java中
- 所有的控制结构都是语句
- 赋值操作是表达式
-
kotlin中
- 除了for/do/do while以外,大多数控制结构都是表达式
- 赋值操作是语句
2.2、类和属性
1、属性
-
在Kotlin中,public是默认的可见性,所以可以省略
-
在Kotlin中,属性是头等的语言特性,完全替代了字段和访问器方法
-
在类中声明一个属性和声明一个变量一样:使用val和var关键字
-
例子
-
class Person(name:String,isMarried:Boolean) { val name:String="Bob" //为什么一定要初始化呢? var isMarried:Boolean=false }
-
val person=Person("Jon",true) println(person.name) println(person.isMarried)
-
-
调用构造方法不需要关键字new
-
可以直接访问属性,但调用的是getter
2、自定义访问器
-
属性访问器的自定义实现
-
假如你声明这样一个矩形,它能判断自己是否是正方形。不需要一个单独的字段来存储这个信息,因为可以随时通过检查矩形的长宽是否相等来判断:
-
代码
-
class Rectangle(val height: Int, val width: Int) { //它这里为什么可以直接写一个get()方法呢,Boolean后面直接跟着get,没有什么衔接的吗 val isSquare: Boolean get() { return height == width } }
-
属性isSquare不需要字段来保存它的值,它只有一个自定义实现的getter。它的值是每次访问属性的时候计算出来的
-
注意,不需要使用带花括号的完整语法,也可以这样写get()=height==width,对这个属性的调用依然不变
-
val rectangle=Rectangle(41,43) println(rectangle.isSquare)
-
-
3、kotlin源码布局:目录和包
-
java把所有的类组织成包。Kotlin和java有类似的包的概念,每一个Kotlin文件都能以一条package语句开头
-
而文件中定义的所有声明(类、函数及属性)都会被放到这个包中
-
Kotlin不区分导入的是类还是函数,它允许使用import关键字导入任何种类的声明。可以导入顶层函数的名称
-
例子
-
Rectangle.kt
package 二.Kotlin基础 import java.util.* class Rectangle(val height: Int, val width: Int) { //它这里为什么可以直接写一个get()方法呢,Boolean后面直接跟着get,没有什么衔接的吗 val isSquare: Boolean get() = height == width } fun createRandomRectangle():Rectangle{ val random= Random() return Rectangle(random.nextInt(),random.nextInt()) }
- Test.kt
package 二.Kotlin基础 import 二.Kotlin基础.createRandomRectangle
-
-