Kotlin基础语法

Kotlin基础

1. 函数

  • 1 . 示例
fun max(a: Int,b: Int): Int{
    return if (a>b) a else b
}
println(max(1,2))
/**
 * Main方法
 */
fun main(args: Array<String>){
    println("Hello World")
}
  • 2 . 语句与表达式:在Kotlin中if是表达式,不是语句,在Kotlin中除了循环(for/do/do...while)外,大多数控制结构都是表达式
  • 3 . 如果函数体写在花括号中,我们说这个函数有代码块体。如果它直接返回一个表达式,它就有表达式体。只有表达式体函数的返回类型可以省略。
  • 4 . 一个函数要么具有并不是代码块的表达式函数体,要么具有包含显示return语句的代码块函数体
IDEA中提供这两种函数风格之间转换的操作

2. 变量

  • 1 . 可变变量和不可变变量

    • val:不可变引用(final)
    • var:可变引用
    • 若变量没有初始化,则需要显示的指定他的类型
    • 不可变变量,只能进行唯一一次初始化
    • val 引用自身是不可变的,但是它指向的对象可能是可变的
    • var允许变量改变自己的值,但他的类型却是不可变的
val a =  "string"
val a: String = "string"

3. 字符串格式化

  • 1 . 示例
fun main (args: Array<String>){
    val name = if (args.size>0) args[0] else "kotlin"
    /**
     * 引用变量,若要打印$符号,则需要转义操作 \$
     */
    println("Hello $name")
    /**
     * 引用表达式
     */
     if(args.size>0){
        println("Hello ,${args[0]}")
     }
     /**
      * 双引号中使用双引号,需要保证内部的双引号在表达式体内
      */
      println("Hello , ${if (args.size>0) args[0] else "kotlin"}")
}
  • 2 . 编译后的代码,创建了一个StringBulider对象,并吧常量部分和变量附加上去

4. 类和属性

  • 1 . 类
class Person(val name: String)
kotlin 中public是默认的可见性,所以省略了
  • 2 . 属性

    • 声明为val的属性是只读的,并自动提供一个getter
    • 声明为var的属性是可变的,并自动提供一个getter和一个setter
    • 对于Java中定义的类,一样可以使用Kotlin语法进行属性访问
    class Person(
        val name: String
        var isMarried: Boolean
    )
    
    val person = new Person("Bob",true)
    println(person.name)
    
  • 3 . 自定义访问器

    • 此方式和声明一个没有参数的函数一样的效果
    • 在Java中访问该属性,直接调用isSquare()即可
    • 不需要使用带花括号的完成语法
    • 通常来说,若描述的是类的属性(特征),则应该声明为属性
    class Rectangle(val height: Int, val width: Int) {
        val isSquare: Boolean
            get() {
                return height == width
            }
            /**
             * 也可以为:
             * get() = height==width
             */
    }
    
    fun main(args: Array<String>) {
        val rectangle = Rectangle(41, 43)
        println(rectangle.isSquare)
    }
  • 4 . 枚举

    • Kotlin中,只有enum关键字在class前面时才表示枚举,其他情况下,仍可以当做普通名称使用
    • 枚举常量中的生命构造方法和属性的语法与之前一样,必须提供属性值
    • 若要在枚举类中定义任何方法,就要使用分号把枚举常量列表和方法定义分开
    /**
     * 普通枚举
     */
     enum class Color {
         RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
     }
    /**
     * 带属性值的枚举
     */
     enum class Color(val r: Int, val g: Int, val b: Int) {
         RED(255, 0, 0), 
         ORANGE(255, 165, 0),
         YELLOW(255, 255, 0), 
         GREEN(0, 255, 0), 
         BLUE(0, 0, 255),
         INDIGO(75, 0, 130), 
         VIOLET(238, 130, 238)
         ;
         /**
          * 此处声明了方法,则枚举最后必须要使用分号;
          */
         fun rgb() = (r * 256 + g) * 256 + b
     }
     
     fun main(args: Array<String>) {
         println(Color.BLUE.rgb())
     }
    
  • 5 . 接口与实现

    • 声明实现类时,使用一个冒号(:)后面跟上接口名称,来标记这个类实现了这个接口
    /**
     * 接口,标记接口,无任何方法
     */
    interface Expr
    
    /**
     * 实现类,使用:来标明实现哪个接口
     */
    class Num(val value: Int) : Expr
    /**
     * 实现类,使用:来标明实现哪个接口
     */
    class Sum(val left: Expr, val right: Expr) : Expr
  • 6 . 类型检查和类型转换

    • 使用is来判断一个变量是否是某种类型,在进行类型判断后,变量会自动转换成响应的类型,无需强制转换,这种方式的转换为智能转换,在使用智能转换时,属性值必须是val属性,而且不能有自定义的访问器
    • 使用as来显示转换,val n = e as Num

5. 目录和包

  • 与Java一样,在文件开头声明package,则该文件中定义的所有声明(类,函数,属性)都会属于这个包
  • 导入包使用import关键字,可以使用*在指定包下的所有类
  • 在Kotlin中,可以吧多个类放在同一个文件中,但应该使用Java的包使用规则
package geometry.shapes

import java.util.Random //使用java的工具包

class Rectangle(val height: Int, val width: Int) {
    val isSquare: Boolean
        get() = height == width
}

fun createRandomRectangle(): Rectangle {
    val random = Random()
    return Rectangle(random.nextInt(), random.nextInt())
}
package geometry.example

import geometry.shapes.createRandomRectangle //使用上面?的对象

fun main(args: Array<String>) {
    println(createRandomRectangle().isSquare)
}

6.选择语句when

  • 1 . 枚举中使用when

    • when是一个有返回值的表达式,因此可以直接返回表达式函数体
    • 分支语句上无需使用break

      enum class Color {
          RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
      }
      
      fun getMnemonic(color: Color) = //直接返回when表达式
          when (color) {
              Color.RED -> "Richard"
              Color.ORANGE -> "Of"
              Color.YELLOW -> "York"
              Color.GREEN -> "Gave"
              Color.BLUE -> "Battle"
              Color.INDIGO -> "In"
              Color.VIOLET -> "Vain"
          }
      
      fun main(args: Array<String>) {
          println(getMnemonic(Color.BLUE))
      }
      
      /**
       * 合并多个选项
       */
      fun getWarmth(color: Color) = when(color) {
          Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
          Color.GREEN -> "neutral"
          Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold"
      }
      
      fun main(args: Array<String>) {
          println(getWarmth(Color.ORANGE))
      }
      
      /**
       * 可导入枚举常量,从而简化代码
       */
      import ch02.colors.Color
      import ch02.colors.Color.*
      
      fun getWarmth(color: Color) = when(color) {
          RED, ORANGE, YELLOW -> "warm"
          GREEN -> "neutral"
          BLUE, INDIGO, VIOLET -> "cold"
      }
      
      fun main(args: Array<String>) {
          println(getWarmth(Color.ORANGE))
      }
  • 2 . 在when结构中使用任意对象

    • 与Java中的switch不一样,可以使用任意对象

      import ch02.colors.Color
      import ch02.colors.Color.*
      
      fun mix(c1: Color, c2: Color) =
              when (setOf(c1, c2)) {  //表达式匹配表达式
                  setOf(RED, YELLOW) -> ORANGE
                  setOf(YELLOW, BLUE) -> GREEN
                  setOf(BLUE, VIOLET) -> INDIGO
                  else -> throw Exception("Dirty color")
              }
      
      fun main(args: Array<String>) {
          println(mix(BLUE, YELLOW))
      }
  • 3 . 不带参数的when

    • 如果没有给when表达式提供参数,则分支条件就是任意的布尔表达式(当做if来使用)

      import ch02.colors.Color
      import ch02.colors.Color.*
      
      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 == BLUE && c2 == VIOLET) ||
              (c1 == VIOLET && c2 == BLUE) ->
                  INDIGO
      
              else -> throw Exception("Dirty color")
          }
      
      fun main(args: Array<String>) {
          println(mixOptimized(BLUE, YELLOW))
      }
  • 4 . 使用when代替if

    • 在kotlin中没有三元运算符,因为if表达式有返回值
    • 在使用代码块时,代码块的最后一条表达式就是结果

      interface Expr
      class Num(val value: Int) : Expr
      class Sum(val left: Expr, val right: Expr) : Expr
      
      /**
       * 使用if
       */
      fun eval(e: Expr): Int =
          if (e is Num) {
              e.value
          } else if (e is Sum) {
              eval(e.right) + eval(e.left)
          } else {
              throw IllegalArgumentException("Unknown expression")
          }
      /**
       * 使用when替换if
       */
      fun eval(e: Expr): Int =
          when (e) {
              is Num ->
                  e.value
              is Sum ->
                  eval(e.right) + eval(e.left)
              else ->
                  throw IllegalArgumentException("Unknown expression")
          }
      /**
       * 复杂表达式体可以使用{}
       */
      fun evalWithLogging(e: Expr): Int =
          when (e) {
              is Num -> {
                  println("num: ${e.value}")
                  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")
          }
      
      fun main(args: Array<String>) {
          println(eval(Sum(Num(1), Num(2))))
      }
  • 5 . 迭代whilefor循环

    • while循环和Java一致
    • 区间数字

      * 一个起始值,一个结束值,使用`..`运算符来表示区间`val oneToTen = 1 .. 10`
      * Kotlin中的区间是包含的或者闭合的,即第二个值始终是区间的一部分
      * 如果能迭代区间中所有的值,这样的区间被称为数列
    • downTo表示降序
    • step表示步长,在普通区间和降序区间中都能使用
    • until表示开区间的结束

      /**
       * 区间[1,100]
       */
      for(i in 1 .. 100 ){
          println(i)
      }
      
      /**
       * 区间[1,100)
       */
      for(i in 1 until 100 ){
          println(i)
      }
      
      /**
       * 区间[100,1] 降序使用downTo
       */
      for(i in 100 downTo 1 ){
          println(i)
      }
      
      /**
       * 区间[100,1? 降序,并且指定步长
       */
      for(i in 100 downTo 1 step 2 ){
          println(i)
      }
      /**
       * 区间[1,100?
       */
      for(i in 1 .. 100 step 2 ){
          println(i)
      }
    • 迭代Map

      fun main(args: Array<String>) {
          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")
          }
      }
    • 使用下标迭代List

      val list = arrayListOf("10","11","12")
      for((index,element) in list.withIndex()){
          println("$index:$element")
      }
    • in/!in运算符,可以检查一个值是否在区间内,或者不在区间内
    • when语句中也可使用in`运算符
    • in运算符使用于所有实现java.lang.Comparable接口的类

      fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
      fun isNotDigit(c: Char) = c !in '0'..'9'
      
      fun main(args: Array<String>) {
          println(isLetter('q'))
          println(isNotDigit('x'))
      }
      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 main(args: Array<String>) {
          println(recognize('8'))
      }
  • Kotlin中的异常

    • 异常不需new关键字来创建实例
    • Kotlin中的throw可以作为另一个表达式的一般部分
    • Kotlin中,无需使用throws关键在来抛出异常,因为Kotlin中并不区分受检测异常和并不受检测异常,所以在代码中可以处理异常,也可不处理异常
    • JDK1.7中的try-with-resources在kotlin中为一个库函数,在后面会介绍
    • try关键字和ifwhen一样,可以作为表达式赋值给一个变量,但必须用花括号把语句主体包裹起来,如果主体包含多个表达式,则try表达式的值就是最后一个表达式的值
    • catch语句中也需要有返回值或者直接return

      import java.io.BufferedReader
      import java.io.StringReader
      
      fun readNumber(reader: BufferedReader): Int? {  //无需throws
          try {
              val line = reader.readLine()
              return Integer.parseInt(line)
          }
          catch (e: NumberFormatException) {  //类型在右边
              return null
          }
          finally {
              reader.close()
          }
      }
      
      fun main(args: Array<String>) {
          val reader = BufferedReader(StringReader("239"))
          println(readNumber(reader))
      }
    • 无finally语句

      
      import java.io.BufferedReader
      import java.io.StringReader
      
      fun readNumber(reader: BufferedReader) {
          val number = try {
              Integer.parseInt(reader.readLine())
          } catch (e: NumberFormatException) {
              return  //return 中断逻辑执行
              //null  //也可返回null
          }
      
          println(number)
      }
      
      fun main(args: Array<String>) {
          val reader = BufferedReader(StringReader("not a number"))
          readNumber(reader)
      }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值