Kotlin基础语法

来源:互联网 发布:长春java公司 编辑:程序博客网 时间:2024/06/01 09:04

    • 1list 和map集合的实例化
    • 可变变量var和不可变变量val
    • 2字符串和数字
    • 3计算器
    • 4函数和函数表达式
    • 5递归调用
    • 6尾递归优化解决计算次数过多堆栈溢出
    • 7idea下kotlin的面向对象思想
    • 8枚举
      • 基本用法
      • 声明一个带属性的枚举类使用when来处理
      • 使用when合并枚举的元素
      • 导入枚举常量后不用限定词就可以访问
    • 9印章类
    • 10委托和代理单例模式
    • 11kotlin自定义访问器
    • 12kotlin中when的使用
      • 在when结构中使用任意对象
      • 使用不带参数的when

1,list 和map集合的实例化

fun main(args: Array<String>) {    var lists=listOf("卖鸡蛋","卖杜蕾斯","买光盘")    for(list in lists){        println(list)    }    for((i,e) in lists.withIndex()){//按照下标位置打印        var a=i+1        println("$a $e")    }}

这里写图片描述

import java.util.TreeMapfun main(args: Array<String>) {    var map=TreeMap<String,String>()    map["好"]="good"    map["学习"]="study"    map["天"]="day"    map["向上"]="up"    println(map["学习"])}

可变变量var和不可变变量val

1.尽管val引用自身是不可变的,但是它指向的对象可能是可变的。例如:下边这段代码是完全有效的
val languages=arrayListOf(“Java”)
languages.add(“Kotlin”)
2.即使var关键字允许变量改变自己的值,但是它的类型却是改变不了 的。例如下边这段代码不会编译:
var answer=42
answer=“no answer”
类型不是期望的类型,就会报错

class Person {    val name: String = ""//只读属性,生成一个字段和一个简单的getter    var isMarried: Boolean = false//可写属性:一个字段,一个getter和一个setter}

不管person这个类定义在java中还是kotlin中,这段代码看起来是一样的,但是如果属性的名称以is打头,getter方法不会增加任何的前缀;而他的setter名称中的is会被替换成set。所以上述代码在Java中,你调用的将是isMarried。

2,字符串和数字

这里写图片描述

3,计算器

fun main(args: Array<String>) {    println("欢迎使用Kotlin加法计算器")    while (true) {        println("请输入第一个数字:")        var numStr1 = readLine()        println("请输入第二个数字:")        try {            var numStr2 = readLine()        var num1: Double = numStr1!!.toDouble()        var num2: Double = numStr2!!.toDouble()        println("${num1}+${num2}=${Math.round(num1 + num2)}")        }catch(e:Exception){            println("输入有误,请重新输入")        }    }}

这里写图片描述

4,函数和函数表达式

fun main(args: Array<String>) {    println("和为:"+add(3,5))    var i={x:Int,y:Int->x+y}//方法2,此时i就等同于add()方法,函数表达式写法    println("方法2和为:${i(4,5)}")//  方法3 函数表达式写法    var j:(Int,Int)->Int={x,y->x+y}    println("方法3和为:${j(67,22)}")}//方法1fun add(a:Int,b:Int):Int=a+b//一行代码下省略大括号和返回值

这里写图片描述

PS :
在kotlin中,if是表达式,不是语句。语句和表达式的区别在于,表达式有值,并且能作为另一个表达式的一部分使用;而语句总是包围着它的代码块中的顶层元素,并且没有自己的值。在java中,所有控制结构都是语句。而在kotlin中,除了循环(for,do和do/while)以外大多数控制结构都是表达式。另一方面,Java中的赋值操作是表达式,在kotlin中反而成了语句。有助于避免比较和赋值之间的混淆,如果函数体写在{}中,我们说这个函数有代码块体。如果他直接返回了一个表达式,他就有表达式体。
例如:
fun max(a:Int,b:Int):Int=if(a>b) a else b
也可以省略返回值类型
fun max(a:Int,b:Int)=if(a>b) a else b
之所以可以这样写,是因为编译器会分析作为函数体的表达式,并把它的类型作为函数的返回类型,这种分析就是kotlin中的“类型推导“,但是也只有表达式体函数的返回值类型可以省略,因为表达式有值,而对于有返回值的代码块体函数,必须显示的写出返回值的类型和return语句

5,递归调用

import java.math.BigIntegerfun main(args: Array<String>) {    println(fact(6))    println(factBig(BigInteger("100")))}fun fact(num:Int):Int{//int最大值21483647    if(num==1)return 1 else return num*fact(num-1)}//超大数字处理fun factBig(num:BigInteger):BigInteger{    if(num==BigInteger.ONE)return BigInteger.ONE else   return num*factBig(num-BigInteger.ONE)}

这里写图片描述

6,尾递归优化,解决计算次数过多堆栈溢出

//解决运算次数太多引起的堆栈溢出问题fun main(args: Array<String>) {    var result1=0    var count=1    println(allold(10000,result1,count))}tailrec fun allold(num:Int,result:Int,count:Int):Int{    println("计算机第${count}次计算,result=${result}")    if(num==0){        return 0    }else{        return allold(num-1,result+num,count+1)    }}

这里写图片描述

7,idea下kotlin的面向对象思想

 参数是静态属性,方法是动态行为class Rect(var height:Int,var with:Int)class Gril(var looks:String,var voice:String){    fun cry(){        println("悲伤逆流成河")    }    fun laugh(){        println("仰天长啸")    }}fun main(args: Array<String>) {    var rect01=Rect(20,30)    var gril=Gril("女汉子","粗犷")    println("长方形的高为:${rect01.height} ")    println("长方形的宽为:${rect01.with} ")    println("女孩的长相:${gril.looks} ")    println("女孩的声音:${gril.voice} ")    gril.cry()    gril.laugh()}

这里写图片描述

8枚举

基本用法

enum class Week{    星期一,星期二,星期三,星期四,星期五,星期六,星期日}fun main(args: Array<String>) {    println(Week.星期五.ordinal)//代表星期一在枚举类中的位置}

声明一个带属性的枚举类,使用when来处理

enum class Color(val r:Int,val g:Int,val b:Int) {//    在每个常量创建的时候指定属性值,结束加分号;    RED(255,201,36),    ORANGE(221,231,78),    YELLOW(101,21,89),    GREEN(0,255,0),    BLUE(0,0,255),    INDIGO(75,0,130),    VIOLET(238,130,238);//    给枚举定义一个方法    fun rgb()=(r*256+g)*256+b}/** * 使用when来处理枚举类 */fun getMnemonic(color: Color)=        when(color){            Color.GREEN -> "绿色"            Color.RED -> "红色"            Color.ORANGE -> "橙色"            Color.YELLOW -> "黄色"            Color.BLUE -> "蓝色"            Color.INDIGO -> "靛蓝"            Color.VIOLET -> "紫罗蓝"        }fun main(args: Array<String>) {    println(Color.BLUE.rgb())    println(Color.INDIGO.ordinal)//对应颜色在枚举中的位置    println("颜色:${getMnemonic(Color.GREEN)},色值:${Color.GREEN.rgb()},位置:${Color.GREEN.ordinal}")//    结果://    255//    5//    颜色:绿色,色值:65280,位置:3}

使用when合并枚举的元素

fun getWarmth(color: Color)=when(color){    Color.RED,Color.ORANGE,Color.YELLOW ->"暖色"    Color.GREEN ->"自然色"//    else -> "冷色"或者    Color.BLUE, Color.INDIGO,Color.VIOLET-> "冷色"}fun main(args: Array<String>) {//    println(Color.BLUE.rgb())//    println(Color.INDIGO.ordinal)//对应颜色在枚举中的位置//    println("颜色:${getMnemonic(Color.GREEN)},色值:${Color.GREEN.rgb()},位置:${Color.GREEN.ordinal}")    println("${getMnemonic(Color.BLUE)}是"+getWarmth(Color.BLUE))//    结果:蓝色是冷色}

导入枚举常量后不用限定词就可以访问

import cho2.colors.Color//导入其它包中定义的Colorimport cho2.colors.Color.*//显示的到时枚举常量就可以使用它们的名称fun getWarmth(color: Color)=when(color){//使用导入的常量名称    RED,ORANGE,YELLOW ->"暖色"    GREEN ->"自然色"//    else -> "冷色"或者    BLUE,INDIGO,VIOLET-> "冷色"}

9印章类

/** * 小母驴,小公驴,小公马生下的孩子 * sealed 子类类型有限, */sealed class Son {    //印章类,子类类型有限,更在意类型    fun sayHello1() {        println("大家好,我是小小驴")    }    fun sayHello2() {        println("大家好,我是小骡子")    }    //    只有以下两种情况,生驴或者骡子,不可能生出来马    class xiaolv : Son()    class xiaoluozi : Son()}fun main(args: Array<String>) {    var son1=Son.xiaolv()    var son2=Son.xiaoluozi()    var son3=Son.xiaolv()    var son4=Son.xiaoluozi()    var list= listOf<Son>(son1,son2,son3,son4)    for (li in list){        if (li is Son.xiaoluozi){            li.sayHello2()        }else{            li.sayHello1()        }    }}

10委托和代理(单例模式)

interface IWash {//洗碗的接口    fun washBowl()}
object BigHeadSon :IWash {//单例模式,只允许有一个BigHeadSon的实例    override fun washBowl() {        println("大头儿子洗碗,一次1块钱")    }}
class SmallHeadFather : IWash by BigHeadSon {    //关键字by表示委托BigHeadSon代替自己去实现Iwash接口    override fun washBowl() {        println("小头爸爸看着小头儿子洗碗,赚了10块钱")//        BigHeadSon().washBowl()//第二次调用构造方法,就会是另一个大头儿子        BigHeadSon.washBowl()//单例模式下的调用        println("小头爸爸看着小头儿子洗完了")    }}
fun main(args: Array<String>) {    var son=BigHeadSon//单利模式下不调用构造,不加括号//    son.washBowl()    var father=SmallHeadFather()    father.washBowl()}

11kotlin自定义访问器

假设你声明这样一个矩形,它能判断自己是否是正方形。不需要单独设置字段来储存这个信息,因为可以随时通过检查矩形的长宽是否相等来判断:

class Rectangle(val height:Int,val width:Int) {//只读属性用来判断    val isSquare:Boolean    get() {        return  height==width//声明属性的getter方法    }//    属性isSquare不需要用字段来保存它的值,它只有一个自定义实现的getter。它的值是每次访问属性的时候计算出来的//    函数表达式的写法如下:    val isSquare2:Boolean=height==width    val isSquare3:Boolean get() = height==width}fun main(args: Array<String>) {    val rectangle=Rectangle(22,34)    println(rectangle.isSquare)    println(rectangle.isSquare2)    println(rectangle.isSquare3)}//结果//false//false//false

12kotlin中when的使用

在when结构中使用任意对象

Kotlin中的when结构比java中的switch强大太多,switch要求必须使用常量(枚举常量,字符串或者数字)作为分支条件,when允许使用任何对象。例如我们写一个函数来混合两种不同的颜色,如果在我们调色板中可以混合,简单的把所有的组合列举出来

fun mix(c1:Color,c2:Color)=        when(setOf(c1,c2)){            setOf(Color.RED,Color.YELLOW)->Color.ORANGE            setOf(Color.YELLOW,Color.BLUE) ->Color.GREEN            setOf(Color.BLUE,Color.VIOLET) ->Color.INDIGO            else -> throw Exception("匹配异常")//自定义抛出异常,不用new        }fun main(args: Array<String>) {    println(mix(Color.YELLOW,Color.RED))    println(mix(Color.YELLOW,Color.BLUE))    println(mix(Color.VIOLET,Color.ORANGE))}//结果://ORANGE//Exception in thread "main" java.lang.Exception: 匹配异常//GREEN

Kotlin标准函数库中有一个setOf函数可以创建出一个Set,他会包含所有指定为函数实参的对象。set这种集合的条目顺序不重要,只要两个set中包含一样的条目,他们就是相等的,也就是说setOf(Color.RED,Color.YELLOW)和setOf(Color.YELLOW,Color.RED)表达的意思是完全一样的

使用不带参数的when

fun mixOptimized(c1: Color, c2: Color) =        when {//没有传实参            (c1 == Color.RED && c2 == Color.YELLOW) ||                    (c1 == Color.YELLOW && c2 == Color.RED) -> Color.ORANGE            (c1 == Color.YELLOW && c2 == Color.BLUE) ||                    (c1 == Color.BLUE && c2 == Color.YELLOW) -> Color.GREEN            (c1 == Color.BLUE && c2 == Color.VIOLET) ||                    (c1 == Color.VIOLET && c2 == Color.BLUE) -> Color.INDIGO            else -> throw Exception("匹配失败")        }fun main(args: Array<String>) {    println(mixOptimized(Color.YELLOW, Color.RED))}

如果没有给when表达式提供参数,分支条件就是任意的布尔表达式。不会创建额外的对象

原创粉丝点击