Kotlin简单入门

作者: 大批 | 来源:发表于2017-05-20 14:40 被阅读236次

    :)

    **V E _**

    我只是搬运工,对搬运工不能有太高的要求。 -_-!

    Hello Kotlin

    • IDE我选择的是idea (不要问我为什么)

    • 新建工程选择Kotlin就可以了

      新建向导
    • 创建完成的目录结构


      工程结构
    • 新建一个Kotlin文件(文件名不用跟 .kt

    • Hello Kotlin代码

    fun main(args: Array<String>) {
        println("Hello Kotlin.")
    }
    
    • 点击左侧的Kotlin图标运行

    • Hello Kotlin就算是走完了~~ 这里还有一些东西要提出来

      • println这个究竟是个什么函数(Ctrl + 鼠标左键
        println源码

    $%%%%%%%%%%%%%%%%%%%%%%%%%%%
    下面高能预警~~ 各种官网语法例子在路上
    ======================> 传送门
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%


    入门

    1.包名
    • 这里的包名可以不用和文件的路径对应(包名可以随意而不用管这个源文件的路径)
    • Kotlin里面的包名(这个和java的语法一样)
    package my.demo
    import java.util.*
    
    • 这里修改上面的Hello Kotlin代码(加入包名的定义 )
    package com.suse.dapi
    fun main(args: Array<String>) {
        println("Hello Kotlin.")
    }
    
    • 我们去看看 out文件夹(可以看到编译之后的class文件其实是和文件夹对应起来了的)

    • 我们修改刚才那个文件的包名再试试


      修改包名
      编译之后class的路径
    • 默认导入的包
      kotlin.*
      kotlin.annotation.*
      kotlin.collections.*
      kotlin.comparisons.* (since 1.1)
      kotlin.io.*
      kotlin.ranges.*
      kotlin.sequences.*
      kotlin.text.*
      java.lang.*
      kotlin.jvm.*
    2.基本数据类型(这里需要注意哈~~ kotlin中所有的都是对象包括int之类的基本类型,so这里说的基本类型其实也是对象哈)
    • Double类型 (64位)
    • Float 类型(32位)
    • Long类型(64位)
    • Int(32位)
    • Short类型(16位)
    • Byte类型(8位)
    
    package com.suse.dapi.demo
    
    fun main(args: Array<String>) {
    
        println("Hello Kotlin.")
    
        val mDouble: Double = 12345.0
        val mFloat: Float = 12323f
        var mLong: Long = 123
        var mInt: Int = 1232
    
        var mInt2 = 123213 //省略了变量类型
    
        mDouble = 123.0  //尝试修改 val 申明的变量
        mLong = 12323
    
        mInt = mDouble.toInt() // double ==> int
        mLong = mInt.toLong() // int ==> long
    
    }
    
    • 这里引入了变量的定义

      • 变量使用var 或者 val来申明(区别是val是只读变量,var是可变变量)
      • 变量使用来申明类型,类型申明也可以省略~ 这就由系统来推断是什么类型
      • 变量还有好些需要注意的地方后面遇到了在提哈
    • 这里还有一个类型转换的方法(每个类型都有,只要是Number类的子类都可以使用,上面提到的基本类型都是Number的子类哈)


      Number源码
    • 字符(字符不能直接和数据比较,但是Char也有 toInt之类的方法)

      var mChar: Char = 'P'
        mChar == 1 // 错误
        mChar == 'a'
        mChar.toByte()
        mChar.toInt()
    
    • 虽然字符也有toInt方法,但是字符并不是Number的子类哈
      Char的部分源码
    • Boolean 布尔类型 ,这个的值有两个 true false

    • 数组类型 Array(系统库提供了一个arrayOf的方法可以创建 Array数组)

        var intArray = arrayOf(1,2,3)  //这里返回的实际上是Array对象
        println(intArray[0])
    
        var intArray: Array<Int> = arrayOf(1,2,3)
        println(intArray[0])
    
    arrayOf源码
    • 系统还提供了一个函数 arrayListOf(实际上就是返回的java里面的ArrayList)

    • 字符串类型String

        var name: String = "dapi"
        var number = "123345666"
    
    • 字符串还有两个有趣的语法(和PHP的字符串类似 ,直接看例子吧)
        var content = """
    
                这里面可以写各种东西
                var name = ""  .....
                这个就类似 html 里面的 <pre></pre>标签
                $name   ====>    ${'$'} // 这个是在字符串里面输出 $
        """
    
        var templ = "i am $name, my number is ${ name + number}" //字符串模板
    
    • 模板里面的 ${} 或者 $变量名 这个就是一个表达式,${}里面还可以调用函数
    3.流程控制
    • 条件语句 if(if可以是一个表达式,也可以有返回值)
        var number1 = 0x0033
        var number2 = 0x0022
        var flag: Boolean = false
        // 一般的 if
        if(number1 > number2){
            flag = true
        }else{
            flag = false
        }
    
    
        // 有返回值的 if
        flag = if (number1 > number2){
            println(".....")
            true // 吧返回值放到最后就可以了
        }else{
            println("-----")
            false
        }
    
        // 表达式的 if
        flag = if (number1 > number2) true else false
    
    • 循环语句 for while do..while
    • for
    /**
         *
         * 以前的 for (int i = 0;i < 10;i++) 循环已经不行了
         * for 专门用来迭代 有 iterator 方法的集合
         *
         */
        var numbers = arrayOf(1,2,3,4,5)
        for (item in numbers){
            //..
        }
        for (item in numbers.iterator()){
            //..
        }
        /**
         *
         * 这里是的index 是下标  0 ,1 ,2, 3, 4,...
         * 查看源码发现 indices 其实返回的就是一个数组 Array 实际上也是使用的 iterator
         *
         */
        for (index in numbers.indices){
            // ..
        }
    
        /**
         * 这里 (index,value) 其实就是下标 和 对应的值
         * 查看源码发现 withIndex 其实返回的就是一个数组 Array 实际上也是使用的 iterator
         *
         */
        for((index,value) in  numbers.withIndex()){
            // ...
        }
    
    • 所以for循环就是专门用来迭代 iterator 的 ,只要 in 的右边返回的是一个包含iterator(): Iterator<T>方法的对象(或者是直接是一个Iterator对象)就可以了

    • while(偷哈懒 ~~)

    while (x > 0) {
        x--
    }
    
    do {
        val y = retrieveData()
    } while (y != null) // y is visible here!
    
    • when语句(这个就和以前的 switch类似 , switch 和 if 的结合)
    
        var number3 = 100
    
        when(number3){
            in 1..101 -> println("1")
            in 10..102 -> println("2")
            else -> println("3")
        }
        // 结果是 3
    
        when{
            number3 in 1..102 -> {
                //...
            }
            number3 == 100 -> {
                //...
            }
            else -> {
                //...
            }
        }
    
    • breakcontinue (这个就是多了一个标签的情况)
        while(number3 < 200){
            if(number3 % 2 == 0){
                continue
            }
            if(number3 == 150){
                break
            }
            number3++
        }
    
        //添加标签的情况
        tagert@
        while(number3 < 200){
            while(number3 < 150){
                break@tagert
            }
            number3++
        }
    

    类和对象(终于可以谈对象了~~)

    • 最简单的类定义
    /**
     * 这样就定义了一个类了
     */
    class MyArray{
        
    }
    
    • 稍微添加一点属性的类
    
    class MyArray{
    
        var items: Array<String> = arrayOf("name1","name2","name3")
        var total =  items.size
    
    }
    
    • 稍微再添加一点方法(仿照着Array这个类来吧 _,方法的语法后面再提)
    class MyArray{
    
        var items: Array<String> = arrayOf("name1","name2","name3")
        var total =  items.size
    
    
        public operator fun iterator(): Iterator<String>{
            return items.iterator()
        }
    
    }
    
    • 不知道还记不记得 前面说的 for 循环可以遍历提供 iterator方法的对象
        var myArray = MyArray()
        for (item in myArray){
            println(item)
        } // 这样写是完全可以的哈
    
    • 我们再来添加几个构造方法(Kotlin里面的构造方法分为两种,就类似 adc 和 辅助 下路两基友)
    • 首先来看主构造方法怎么添加
    class MyArray public constructor(names: Array<String>){
    
        var items: Array<String> = arrayOf("name1","name2","name3")
        var total =  items.size
    
        /**
         * 主构造就是申明在 类的定义后面...  有点智障啊~~
         * 主构造的参数是在 init 里面访问的~~ 也只有这里访问
         * 这个init 方法就像静态代码块一样 放在前面的先执行  这个也是有点智障啊~~
         */
        init {
            items = names
        }
    
        public operator fun iterator(): Iterator<String>{
            return items.iterator()
        }
    
    }
    
    • 看了上面那个智障的代码 有没有想打人啊~~ (Kotlin提供了一个简单的写法,将属性 和 主构造写到一起去)
    class MyArray public constructor(var items: Array<String>,var total: Int){
    
        var orther: String = "tag" //这里一样可以写其他的属性
    
        public operator fun iterator(): Iterator<String>{
            return items.iterator()
        }
    
    }
    
    • 辅助构造函数,这个就和C#很类似了(官方叫的是二级构造函数,也是一个智障)(不管怎么样~~ 主构造都感觉有点智障的感觉)

    • 一般的辅助构造函数

    class MyArray {
    
        var items: Array<String> = arrayOf("name1","name2","name3")
        var total =  items.size
        
        constructor(name: Array<String>){
            items = name
        }
    
        public operator fun iterator(): Iterator<String>{
            return items.iterator()
        }
    }
    
    • 上面是没有主构造函数的时候的写法~(还算正常),当有了主构造函数之后就要 主动调用主构造函数
    class MyArray constructor(size: Int){
    
        var items: Array<String> = arrayOf("name1","name2","name3")
        var total =  items.size
    
        init {
            total = size
        }
    
        constructor(name: Array<String>,size_: Int) : this(size_){
            items = name
        }
    
        public operator fun iterator(): Iterator<String>{
            return items.iterator()
        }
    
    }
    
    • 有了类就可以创建对象了(其实前面都已经用了 没有new 没有 new 没有 new)
    var myArray = MyArray()
    
    • Kotlin中也有类似Java中Object的类Any,所有类的父类(什么鬼~~)

      Any源码
    • 最一般的继承(只有类前面有 open 修饰的类才能被继承)

    open class MyArray {
        var size: Int = 0
    }
    
    /**
     * 继承的时候需要调用父类的构造方法   这里是默认的构造方法
     */
    class MyArray2 : MyArray() {
    }
    
    • 父类没有默认构造方法的时候
    open class MyArray constructor(size: Int){
        var size: Int = 0
    }
    
    /**
     * 继承的时候需要调用父类的构造方法
     */
    class MyArray2 constructor(size: Int): MyArray(size) {
    }
    
    /**
     *
     * 这里是不会生成默认的构造方法的~~
     *
     */
    open class MyArray {
        var size: Int = 0
        constructor(size: Int){
        }
    }
    
    /**
     * 继承的时候需要调用父类的构造方法 这里就不能调用父类的无参数构造了
     */
    class MyArray2 constructor(size: Int): MyArray(size) {
    }
    
    
    • 不在主构造函数里面初始化父类(使用super来初始化)
    /**
     *
     * 这里是不会生成默认的构造方法的~~
     *
     */
    open class MyArray {
    
        var size: Int = 0
    
        constructor(size: Int){
    
        }
    
    }
    
    /**
     * 继承的时候需要调用父类的构造方法 使用 super
     */
    class MyArray2 : MyArray{
    
        constructor(size: Int) : super(size)
    
    }
    
    • 方法的复写(方法的讲解放到 后面再说)(能看到这里的 耐心都挺好啊~~ )
    /**
     *
     * 这里是不会生成默认的构造方法的~~
     *
     */
    open class MyArray {
        var size: Int = 0
        constructor(size: Int){
        }
        open fun say(){
            // ..
        }
    }
    
    /**
     * 继承的时候需要调用父类的构造方法 使用 super
     */
    class MyArray2 : MyArray{
        constructor(size: Int) : super(size)
        override fun say(){
        }
    }
    
    • 还有一个需要注意的是 如果父类 和 实现的接口中包含同一个方法 则必须重写

    • 抽象类这个就和java一样了~~

    /**
     *
     * 这里是不会生成默认的构造方法的~~
     *
     */
    open abstract class MyArray {
    
        var size: Int = 0
    
        constructor(size: Int){}
    
        open fun say(){
            // ..
        }
    
        abstract fun aSay()
    
    }
    
    /**
     * 继承的时候需要调用父类的构造方法 使用 super
     */
    class MyArray2 : MyArray{
    
        override fun aSay() {
    
        }
    
        constructor(size: Int) : super(size)
    
        override fun say(){}
    
    }
    
    • 类里面的属性 (get 和 set方法已经有了默认的实现了~~ 也比较简便)
    
    class User{
        var nickName: String = "dapi"  //这里的属性必须有默认值
        var name: String  //这个不用设置默认值
            get() = "dapi"
            set(value){
                name = value
            }
        var number: String = "122323232"
            set(number) {
                this.number = number
            }
    }
    
    • 属性这里需要注意的地方就是 基本类型是必须有初始值的~~(如果不想设置初始值就要使用下面的方法)
    
    class User{
    
        var nickName: String = "dapi"  //这里的属性必须有默认值
    
        var name: String  //这个不用设置默认值
            get() = "dapi"
            set(value){
                name = value
            }
    
        var number: String = "122323232"
            set(number) {
                this.number = number
            }
    
        lateinit var items: Array<String>
        lateinit var tag: String
    
    }
    
    • 接口(Kotlin中的接口和java8中的接口很类似,可以有方法实现)
    
    interface Flyable{
    
        fun fly()
    
        fun 呵呵(){
    
        }
    
    }
    
    class User : Flyable{
    
        override fun fly() {
            // do fly
        }
    
        var nickName: String = "dapi"  //这里的属性必须有默认值
    
        var name: String  //这个不用设置默认值
            get() = "dapi"
            set(value){
                name = value
            }
    
        var number: String = "122323232"
            set(number) {
                this.number = number
            }
    
        lateinit var items: Array<String>
        lateinit var tag: String
    
    }
    
    • 可见性修饰符privateprotectedinternalpublic(默认)(这个和java类似的哈~~)

    • 扩展(什么鬼,感觉是个黑科技啊

    
        var arrs = arrayOf("xx")
        arrs.test()
    
    fun Array<String>.test(){
        println("test")
    }
    
    • 数据类(这个感觉很有用~~)(就是 这些类仅仅就是用来存一些数据信息,里面不会有业务逻辑)
    data class Person(var name: String,var number: String)
    
    • sealed 修饰的类 (这种类的子类只能是和父类在同一个文件中~)
    sealed class Expr
    data class Const(val number: Double) : Expr()
    data class Sum(val e1: Expr, val e2: Expr) : Expr()
    object NotANumber : Expr()
    
    fun eval(expr: Expr): Double = when (expr) {
        is Const -> expr.number
        is Sum -> eval(expr.e1) + eval(expr.e2)
        NotANumber -> Double.NaN
    }
    

    关于类的东西还有一些没有提到~ 自己去看官网吧~ 我都还不熟


    函数

    • 最一般的函数(没有参数,没有返回值)
    fun doSome(){
        println("...")
    }
    
    • 函数的定义使用的是 fun 关键字

    • 有参数的函数(有参数,没有返回值的函数)

    fun doSome(message: String,other: String){
        println("... $message ... $other")
    }
    
    • 有返回值得函数(有返回值,没有参数)
    fun doSome(): Int{
        println("...")
        return 0
    }
    
    • Kotlin里面有一个类似void的关键字 Unit(默认可以不写),当一个函数返回值为空的时候可以使用
    fun doSome(): Unit{
        println("...")
    }
    
    • 有返回值和参数的函数
    fun doSome(message: String,name: String): Int{
        println("...")
        return 0
    }
    
    • 表达式函数(说表达式其实也不准确~~ 就说没有大括号的函数~)
    fun doSome() = println("xxx") //可以没有返回值哈 等号右边是函数体
    fun doSome(): String = "dapi" // 这个也可以有返回值
    

    Lambda表达式

    • 这个表达式有两部分构成,一个是参数列表 一个是返回值
    • 首先来看怎么定义
        /**
         *
         * () 里面的就是参数列表  -> 右边的就是返回值类型
         *
         */
        var sum: (Int,Int) -> Int // 定义一个求和的 表达式
        var max: (Int,Int) -> Int // 定义一个求最大值得表达式
    
    • 在定义的时候赋初值
        /**
         *
         * () 里面的就是参数列表  -> 右边的就是返回值类型
         *
         */
        var sum: (Int,Int) -> Int = {number1,number2 -> number1 + number2}
        var max: (Int,Int) -> Int = {x,y -> if (x > y) x else y}
    
    • 这个表达式也可以做函数的参数
    fun doSome(message: String,transform: (String) -> String): String{
        return transform(message)
    }
    doSome("dapi",{messag -> messag.toUpperCase()})  // DAPI
    
    • 如果只有一个参数可以用it代替这个参数
    fun doSome(message: String,transform: (String) -> String): String{
        return transform(message)
    }
    doSome("dapi",{it.toUpperCase()})  // DAPI
    

    Nothing is certain in this life. The only thing i know for sure is that. I love you and my life. That is the only thing i know. have a good day

    相关文章

      网友评论

      本文标题:Kotlin简单入门

      本文链接:https://www.haomeiwen.com/subject/ejwuxxtx.html