美文网首页
kotlin中的程序结构

kotlin中的程序结构

作者: e小e | 来源:发表于2018-04-05 17:15 被阅读68次

目录

  • val,var关键字
  • 函数
  • Lambda表达式
  • 类成员
  • 运算符
  • 表达式
  • 循环语句(for循环,while循环,continue,break)
  • 异常捕获
  • 具名参数,变长参数,默认参数

val,var关键字

kotlin中关键字val用来表示常量,var用来表示变量

val a : String = "Hello world"
var b : String = "Hello world"

a的值不能改变,b的值可以改变
另外,kotlin中有类型推导的功能,可以不用写String类型例如下面这样

val c = "Hello world"

可以推倒出c是String类型.
kotlin中的val和java中的final有什么区别?
java中的final是编译期常量,什么是编译期常量?就是在编译的时候就把引用换成值。而kotlin中的val修饰的只是一个不能改变值的变量(可以通过反射改变),如果我们想要在kotlin中定义编译期常量我们可以加上const关键字.

函数

kotlin中函数定义

fun main(args: Array<String>) : Unit{
    
}

Unit是返回类型,它相当于java中的Void关键字声明

fun sum(arg1 : Int,arg2: Int) : Int{
    return arg1 + arg2
}

当然也是可以返回其它的类型

fun main(args: Array<String>) : Unit{
    val arg1 = args[0].toInt()
    val arg2 = args[1].toInt()
    println("$arg1 + $arg2 = ${sum(arg1,arg2)}")
}

对于返回值只有一个表达式的函数还可以简写成:

fun sum(arg1 : Int,arg2: Int) = arg1 + arg2

匿名函数

val int2Long = fun(arg : Int) : Long{
    return arg.toLong()
}

Lambda表达式

关于Lambda表达式请参见 :https://www.jianshu.com/p/78f7c6d169f2

类成员

如何在kotlin中声明一个类

class MM(name : String,age : Int,voice : String){
    fun sing(name : String){
        println("sing $name")
    }
}

声明及使用

fun main(args: Array<String>) {
    val mm = MM("",22,"未知")
    mm.sing("天鹅湖")
}

在java中声明一个成员变量,通常会有set和get方法如下

public class JavaA {
    private int b = 0;

    public int getB() {
        System.out.println("some one tries to get b.");
        return b;
    }

    public void setB(int b) {
        System.out.println("some one tries to set b.");
        this.b = b;
    }
}

但是在kotlin中默认是不需要set和get方法的

open class A{
    var b = 0
}

直接就可以使用

var a : A = A()
a.b

这和java中声明成员变量为public差不多. 其实也是可以设置get/set方法的,如下

open class A{
    var b = 0
        get() = field
        set(value){ field = value}
}

另外,kotlin中存在一种延迟加载的机制,var可以用lateinit关键字,val可以用lazy关键字.

open class A{
    var b = 0
    lateinit var a : String
    lateinit var d : X
    val e : X by lazy{
        println("init X")
        X()
    }
}

运算符

在java当中,运算符都是定死的,+-*/, 1+1一定等于2,但是在kotlin中运算符是可以自定义的,也就是说1+1可以不等于2.
官网详情:https://kotlinlang.org/docs/reference/operator-overloading.html
下面我们自定义加法运算符,做一个复数相加的运算

class Complex(var real:Double,var imaginary:Double){
    operator fun plus(other:Complex) : Complex{
        return Complex(real+other.real,imaginary+other.imaginary)
    }

    override fun toString(): String {
        return "${real}+${imaginary}"
    }
}
fun main(args: Array<String>) {
    val c1 : Complex = Complex(3.0,4.0);
    val c2 : Complex = Complex(4.0,5.0);
    println(c1 + c2)
}

最终输出

7.0+9.0i

运算符重写只对参数个数做要求,对参数和返回值类型不做要求
例如我可以重写plus如下:

operator fun plus(other:Int) : Complex{
    return Complex(real+other,imaginary+other)
}
operator fun plus(other:Int) : Int{
   return other
}

以上都是可以的, 另外我们再来看看infix中缀表达式

if ("-name" in args){        
}

使用in其实是关联到了Array中的contains函数,他返回是否存在该元素

public operator fun <@kotlin.internal.OnlyInputTypes T> Array<out T>.contains(element: T): Boolean {
    return indexOf(element) >= 0
}

我们也可以使用infix定义其它的运算符号如 on.

class Desk

class Book{
    infix fun on(desk: Desk):Boolean{
        return false
    }
}

fun main(args: Array<String>) {
    val d = Desk()
    val b = Book()
    if (b on d){
        
    }
}

表达式

if表达式可以有返回值

class Kotlin{
    val DEBUG = 1
    val USER = 2
    fun test(){
        var rule = true
        var mode = if (rule){
            DEBUG
        }else{
            USER
        }
    }
}

when表达式
java中的swich表达式针对的类型有限(只能和int类型兼容,1.7增加了String和枚举),在kotlin中使用when来替代swich表达式

fun test(){
        val x = 5
        when(x){
            is Int -> println("Hello $x")
            in 1..100 -> println("$x is in 1..100")
            !in 1..100 -> println("$x is not in 1..100")
        }
    }

同时when也是有返回值的

fun test(){
    val a = A()
       var mode = when {
        a == null -> 1 else ->0
    }
}

循环语句(for循环,while循环,continue,break)

for循环的几种基本形式

val array = intArrayOf(1, 2, 3)
        for (arg in array){
            println(arg)
        }
for ((index,value) in array.withIndex()){
       println("$index -> $value")
}
for (indexValue in array.withIndex()){
      println("${indexValue.index} -> ${indexValue.value}")
}

关于in操作符


image.png

可以看出in操作符的对象必须满足实现以上三个方法,下面我们来自定义迭代类,然后使用in进行迭代输出

class MyIterator(val iterator: Iterator<Int>){
        operator fun next(): Int{
            return iterator.next()
        }
        operator fun hasNext(): Boolean{
            return iterator.hasNext();
        }
    }
class MyIniList{
        private val list = ArrayList<Int>()

        fun add(int : Int){
            list.add(int)
        }

        fun remove(int : Int){
            list.remove(int)
        }

        operator fun iterator():MyIterator{
            return MyIterator(list.iterator())
        }
    }

最终输出

 val list = MyIniList()
        list.add(1)
        list.add(2)
        list.add(3)
        for (arg in list){
            println(arg)
        }

while语句

var x = 5
while (x > 0){
     println(x)
     x--
}
do {
    println(x)
    x--
}while (x > 0)

continue,break

class Loop2{

    class Student{
        fun isNotClothedProperly():Boolean{
            return false
        }
    }

    fun test(){
        val students = ArrayList<Student>()
        val you = Student()
        for (student in students){
            if (student == you) continue
            if (student.isNotClothedProperly()){
                break
            }
        }
    }
}

异常捕获

class Sum{
    fun input(args :Array<String>){
        try {
            val arg1 = args[0].toInt()
            val arg2 = args[1].toInt()
            println("$arg1+$arg2=${arg1+arg2}")
        }catch (e : NumberFormatException){
            println("您确定输入的是整数吗?")
        }catch (e : ArrayIndexOutOfBoundsException){
            println("您确定输入的是两个整数吗?")
        }catch (e : Exception){
            println("程序出现了未知异常.${e.message}")
        }finally {
            println("谢谢使用")
        }
    }
}

具名参数,变长参数,默认参数

具名参数
具名参数的意思是,在传入参数的同时给定参数名字

class Test{
    fun test(){
        sum(arg2 = 3,arg1 = 2)
    }
    fun sum(arg1 : Int, arg2 : Int){
        
    }
}

变长参数
参数的个数可以任意改变

class Test{
    
    fun test(){
        hello(1,2,3,4,5,string = "hello")
    }
    
    fun hello(vararg ints : Int, string: String){
        ints.forEach(::println)
    }
}

变长参数还支持一个特性

fun test(){
     val array = intArrayOf(1,3,4,5)
     hello(*array,string = "hello")
}

*表示把数组展开成一个个元素传进去.

默认参数
默认参数参数可以给参数设定一个默认值,调用函数的时候可以不用传该参数,具体使用如下

class Test{
    fun test(){
        val array = intArrayOf(1,3,4,5)
        hello(ints = *array,string = "hello")
    }

    fun hello(double: Double = 3.0,vararg ints : Int, string: String){
        ints.forEach(::println)
    }
}

以上是我对kotlin中程序结构相关内容的总结.

相关文章

网友评论

      本文标题:kotlin中的程序结构

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