1 函数和变量
1.1 hello world
fun print() {
println("Hello, world!")
}
1.2 函数
fun max(a: Int, b: Int): Int {
//if是表达式,可以输出值
return if (a > b) a else b
}
1.3 变量
//var:可变引用
var a = 42
//val:不可变引用
val c = 5
1.4 字符串模板
fun testString() {
var name = if (1 > 0) "A" else "B"
println("name = $name")
}
输出结果
name = A
2 类和属性
2.1 属性
class PersonB(
var name: String,
var isMarried: Boolean
)
fun useClass(){
val person = PersonB("Bob",false)
person.isMarried = true
println("person.isMarried = ${person.isMarried}")
println("person.name = ${person.name}")
}
输出结果
person.isMarried = true
person.name = Bob
2.2 自定义访问器
class Rectangle(val height:Int, val width:Int){
val isSquare:Boolean
get(){ //声明属性的getter
return height == width
}
}
fun customAttribute(){
var rectangle = Rectangle(10,20)
println("rectangle is Square ${rectangle.isSquare}")
}
输出结果
rectangle is Square false
2.3 目录和包
1 当前文件的包
com.yl.kt.Test
2 引入其他包下的方法
import com.yl.kt.testPackage
fun testPackageA(){
testPackage()
}
3 枚举和when
3.1 声明枚举类
1 声明一个简单的枚举类
enum class Color{
RED, ORANGE,YELLOW,GREEN,BLUE,INDIGO,VIOLET
}
2 声明一个带属性的枚举类
enum class ColorB(var r:Int, val g:Int, b:Int){
// 在每个常量创建时,指定属性值
RED(255, 0, 0), ORANGE(255, 165, 0), BLUE(0, 0, 255); //这里的分号必须有
//给枚举定义一个方法
fun rgb() = (r * 256 + g) * 256 + b
}
fun testEnum(){
println("ColorB.BLUE.rgb() = ${ColorB.BLUE.rgb()}")
}
输出结果
ColorB.BLUE.rgb() = 30
3.2 使用“when”处理枚举类
1 使用when来选择正确的枚举值
fun getMnumnic(color: Color) = when(color) {
Color.RED -> "Richard"
Color.ORANGE -> "Of"
Color.YELLOW -> "York"
Color.GREEN -> "Gave"
Color.BLUE -> "Battle"
Color.INDIGO -> "In"
Color.VIOLET -> "Vain"
}
2 在一个when分支上合并多个选项
fun getWarmth(color:Color) = when(color){
Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
Color.GREEN -> "neutral"
Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold"
}
fun testEnum2(){
getMnumnic(Color.VIOLET)
println("getMnumnic(Color.VIOLET) = ${getMnumnic(Color.VIOLET)}")
println(" getWarmth(Color.RED) = ${ getWarmth(Color.RED)}")
}
输出结果
getMnumnic(Color.VIOLET) = Vain
getWarmth(Color.RED) = warm
3 导入枚举常量后不用限定词就可以访问
import com.yl.kt.chapter_2.Test.Color.*
fun getWarmth2(color:Color) = when(color){
RED, ORANGE, YELLOW -> "warm"
GREEN -> "neutral"
BLUE, INDIGO, VIOLET -> "cold"
}
3.3 在“when”结果中使用任意对象
fun mix(c1: Color, c2: Color) = when (setOf(c1, c2)) { //"when"表达式的实参可以是任何对象,它被检查是否与分支条件相等
setOf(RED, YELLOW) -> ORANGE
setOf(YELLOW, BLUE) -> GREEN
setOf(BLUE, VIOLET) -> INDIGO
else -> throw Exception("Dirty color")
}
3.4 使用不带参数的“when”
fun mixOptimized(c1: Color, c2: Color) = when {
(c1 == RED && c2 == YELLOW) || (c1 == YELLOW && c2 == RED) -> ORANGE
(c1 == YELLOW && c2 == BLUE) || (c1 == BLUE && c2 == YELLOW) -> GREEN
(c1 == VIOLET && c2 == BLUE) || (c1 == BLUE && c2 == VIOLET) -> INDIGO
else -> throw java.lang.Exception("Dirty color")
}
3.5 和并类型检查和转换
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
//1 使用if层叠对表达式求值
fun eval(e: Expr): Int {
if (e is Num) {
val n = e as Num
return n.value
}
if (e is Sum) {
return eval(e.right) + eval(e.left)
}
throw IllegalArgumentException("Unknown expression")
}
3.6 用"when"代替"if"
//1 使用有返回值的if表达式
fun eval2(e: Expr): Int =
if (e is Num) {
e.value
} else if (e is Sum) {
eval2(e.right) + eval2(e.left)
} else {
throw IllegalArgumentException("Unknown expression")
}
//2 使用when代替if层叠
fun eval3(e: Expr): Int =
when (e) {
is Num -> e.value
is Sum -> eval3(e.right) + eval3(e.left)
else -> throw IllegalArgumentException("Unknown expression")
}
3.7 代码块作为"if"和"when"的分支
fun evalWithLogging(e: Expr): Int =
when (e) {
is Num -> {
println("num:${e.value}")
e.value //代码块中的表达式,如果e的类型是Num 就返回e.value
}
is Sum -> {
val left = evalWithLogging(e.left)
val right = evalWithLogging(e.right)
println("sum: $left + $right")
left + right
}
else -> throw IllegalArgumentException("Unknown expression")
}
4 while和for循环
4.1 "while"循环
fun testWhile() {
while (true) {
}
}
fun testDoWhile() {
do {
} while (true)
}
4.2 迭代数字: 区间和队列
//1 使用 .. 运算符 来表示区间
val onToTen = 1..10
//2 使用when实现Fizz-Buzz游戏
fun fizzBuzz(i: Int) = when {
i % 15 == 0 -> "FizzBuzz "
i % 3 == 0 -> "Fizz "
i % 5 == 0 -> "Buzz "
else -> "$i "
}
fun testFor() {
for (i in 1..100) {
print(fizzBuzz(i))
}
}
//3 迭代带步长的区间
fun testFor2() {
for (i in 100 downTo 1 step 2) {
print(fizzBuzz(i))
}
}
4.3 迭代map
//1 初始化并迭代map
fun iteratorMap() {
val binaryReps = TreeMap<Char, String>()
for (c in 'A'..'F') {
val binary = Integer.toBinaryString(c.toInt())
binaryReps[c] = binary
}
for ((letter, binary) in binaryReps) {
println("$letter = $binary")
}
}
输出结果
//A = 1000001
//B = 1000010
//C = 1000011
//D = 1000100
//E = 1000101
//F = 1000110
4.4 使用"in"检查集合和区间的成员
//1 使用"in"检查区间的成员
fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
fun isDigit(c: Char) = c in '0'..'9'
fun testIn() {
var isLetter = isLetter('A')
var isDigit = isDigit('a')
println("isLetter = $isLetter")
println("isDigit = $isDigit")
}
//2 用in检查作为when分支
fun recognize(c: Char) = when (c) {
in '0'..'9' -> "It's a digit!"
in 'a'..'z', in 'A'..'Z' -> "It's a letter!"
else -> "I don't know..."
}
fun testInWithWhen() {
println(recognize('a'))
println(recognize('1'))
}
5 kotlin中的异常
fun testException(percentage: Int) {
if (percentage !in 0..100) {
throw IllegalArgumentException("A percentage value must be between 0 and 100 percentage = $percentage")
}
}
//throw 作为一个表达式
fun testException2(number: Int) {
val percentage = if (number in 0..100) {
number
} else {
throw IllegalArgumentException("A percentage value must be between 0 and 100 percentage = $number")
}
}
5.1 “try” “catch” 和 “finally”
//1 像在java中一样使用try
fun readNumber1(reader: BufferedReader): Int? {
try {
val line = reader.readLine()
return Integer.parseInt(line)
} catch (e: NumberFormatException) {
return null
}
finally {
reader.close()
}
}
5.2 “try” 作为表达式
//1 把try当做表达式使用
fun readNumber2(reader:BufferedReader){
var number = try{
Integer.parseInt(reader.readLine())
}catch (e:NumberFormatException){
return
}
println("number = $number")
}
//2 在catch 中返回值
fun readNumber3(reader:BufferedReader){
val number = try{
Integer.parseInt(reader.readLine())
}catch (e:NumberFormatException){
null
}
println(number)
}