常量或变量的定义
定义一个变量 使用关键字 var
var stringVar: String = "I'm a String"
定义一个常量 使用关键字 val
val PI = 3.14f
给常量或变量赋值时,可省略数据类型的声明
var a: Int = 0
var b = 1
函数的定义
定义一个函数,使用关键字 fun
fun add(a: Int, b: Int): Int {
return a + b
}
全局变量和局部变量
对于全局变量,不想立即赋值,可使用关键字 lateinit
class varInitialization {
var justInitStr: String = ""
lateinit var lateInitStr: String
fun initialize() {
var localStr: String
localStr = ""
justInitStr = ""
lateInitStr = ""
}
}
常见的基本数据类型
Byte、Short、Int、Long、Float、Double、String
var byteVar: Byte = Byte.MAX_VALUE
var shortVar: Short = Short.MAX_VALUE
var intVar: Int = Int.MAX_VALUE
var longVar: Long = Long.MAX_VALUE
var floatVar: Float = Float.MAX_VALUE
var doubleVar: Double = Double.MAX_VALUE
var stringVar: String = "I'm a String"
字符串模板
生成字符串模板,使用关键字$
fun generateStringTemplate(mallPlatform: String, phoneBrand: String, price: Float): String {
var template = "双12快到了,我在${mallPlatform}买了一部${phoneBrand}手机,花了${price}元钱。"
return template
}
fun printLog(msg:String){
println("$msg")
}
if…else
fun controlCondition() {
var a = 10
var b = 9
var result: String;
if (a > b) {
result = "${a}>${b}"
} else if (b > a) {
result = "${b}>${a}"
} else {
result = "${a}=${b}"
}
println(result)
}
字符串比较
fun compareString() {
var str1 = "String"
var str2 = "string"
//这里的== 相当于java中的equals方法 而java中的== 是比较内存地址
println(str1 == str2)
println(str1.equals(str2, true))
}
空值处理
不加?变量不能为空,加?变量可以为空
var notNullVal: String
var canNullVal: String?
fun hotSth(sth: String?): String {
return "热${sth}"
}
When表达式
fun useWhenExp() {
var score = 10;
when (score) {
10 -> println("wonderful")
9 -> println("well done")
8 -> println("good")
7 -> println("ok")
else -> println("need to work hard")
}
}
集合数据类型
//定义了一个整数数组 取值范围是[1,100]
var nums1 = 1..100
//定义了一个数组 取值范围是[1,100)
var nums2 = 1 until 100
//定义了一个只读列表
var buyList = listOf("柴", "米", "油", "盐")
//定义了一个TreeMap
var map = TreeMap<String, String>()
map["好"] = "good"
map["学习"] = "study"
map["天"] = "day"
map["向上"] = "up"
for循环
fun useLoopExp() {
//定义了一个数组 取值范围是[1,100)
var nums2 = 1 until 100
var sum2 = 0;
//step表示声明取数间隔
for (num in nums2 step 2) {
sum2 = sum2 + num
}
println("sum2的值为:${sum2}")
//定义了一个数组 取值是将数组nums1反转
var nums3 = nums1.reversed();
println("数组nums3中数字总数为:${nums3.count()},其中第一个数字是:${nums3.first}")
}
函数表达式
fun add(a: Int, b: Int): Int {
return a + b
}
fun add2(a: Int, b: Int): Int = a + b
fun useFunctionExp() {
//定义了一个函数i 接受参数a、b 返回它们的和,等号后面就是函数的Lambda表达式
var i = { a: Int, b: Int -> a + b }
//函数i的另外一种写法,相比前者其实就是抽取了参数及返回值的类型
var j: (Int, Int) -> Int = { a, b -> a + b }
//这里的i和j可以当作具有函数功能的变量
println("${add(1, 2)}")
println("${add2(1, 2)}")
println("${i(1, 2)}")
println("${j(1, 2)}")
}
默认参数和具名参数
对于Android开发者,可能会经常遇到这样的情况:不同业务场景下启动同一个Activity需要传递的参数类型及数量不固定,往往是不断重载启动方法。Kotlin中对函数参数的设计,正好可以避免此类问题。
val Pi = 3.14f
fun kownFunctionArgs() {
var rectArea = getRectArea(5.0f, 4.0f)
//由于使用了默认参数,所以调用时需要显式指明具名参数
var circularArea = getCircularArea(radius = 5.0f)
}
fun getRectArea(height: Float, width: Float): Float {
return height * width
}
//参数PI的默认值为常量Pi对应的值3.14 PI叫做默认参数 radius叫做具名参数
fun getCircularArea(PI: Float = Pi, radius: Float): Float {
return PI * radius * radius
}
递归调用及尾递归优化
//当计算的数字巨大时,普通的Int、Long类型会溢出,可使用BigInteger这一类API进行计算
普通递归
fun caculateFactorial(n: BigInteger): BigInteger {
if (n == BigInteger.ONE) {
return BigInteger.ONE
} else {
return n * caculateFactorial(n - BigInteger.ONE)
}
}
尾递归优化
/**
* 因为子问题的答案被重复计算。只要输入的参数稍微大点(例如100),程序就会因创建过多的堆栈而挂掉。
采用尾递归算法,可以极大地提高运行效率
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归。
需要说明的是,只有当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这样的递归调用才是尾递归。
*/
tailrec fun accumulateOptim(n: Int, a: Int): Int {
if (n == 0) {
return 0
} else if (n == 1) {
return a
} else {
return accumulateOptim(n - 1, n + a)
}
}
我们不妨推导一下
设累加数列h(n)=n+n-1+n-2+⋯+2+1+0
则有
○1h(n)-h(n-1)=n
○2当n足够大时=> h(n)= f(n,a)=f(n-1,g(n,a))
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归。 需要说明的是,只有当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这样的递归调用才是尾递归。
根据尾递归函数定义,不妨将f(n,a)用代码表示出来
fun f(n: Int, a: Int): Int {
if (n == 0) {
return 0
} else if (n == 1) {
return a
} else {
return f(n - 1, g(n,a))
}
}
接下来就是如何推导g(n,a)
根据条件○2我们可以写出如下等式
=>当n=0时,f(0,a)=0
当n=1时,f(1,a)=a;即a=1
当n=2时,f(2,a)=f(1,g(2,a))=g(2,a)
当n=3时,f(3,a)=f(2,g(3,a))=f(1,g(2,g(3,a)))=g(2,g(3,a))
当n=4时,f(4,a)=f(3,g(4,a))=f(2,g(3,g(4,a)))=f(1,g(2,g(3,g(4,a))))= g(2,g(3,g(4,a)))
...
我们已经可以看出一些端倪了,g算子其实就是等式
h(n)=n+n-1+n-2+⋯+2+1+0
右边反复出现的加法算子,所以
g(n,a)=n+a
同理我们可得到累乘数列h(n)=n*(n-1)*(n-2)*…*2*1
的g算子为
g(n,a)=n*a