Kotlin系列 - 基础类型结构细节小结(一)

前言: 用了kotlin差很少半年时间了,以前是看了中文版的kotlin入门的,后面使用的时候总感受有些细节的东西并无很好的理解,专门买了份kotlin的教程,感受不错,本文也是中途一些细节的整理。java

1. 成员变量&空类型

  • varlateinit延迟初始化,vallazy延迟初始化
  • 类型后面跟?表示可空类型,类型后面不跟?表示不可空类型
  • 可空类型使用 :
  1. ?.表示若为null,则返回null,不然返回返回对象继续逻辑操做。
  2. !!.表示强制认定为不为null使用可是最好本身作一下判断,否则等下抛空异常
  3. ?:表示当前面为null的时候,返回?:后面的值
class X
lateinit var mStr:String     //var 延迟初始化
val x:X by lazy{    // val延迟初始化
  X()
}  

var name: String? = ""
fun a(x: Any): Int {
   return name?.length ?: 0
}


val nullable:String? = null //正确 能够为空
val notNull:String = null  //报错 不能为空

nullable.length //错误 ,不能够直接使用
notNull.length  //正确,不可空的值能够直接使用
nullable!!.length //正确,强认定不为null
nullable?.length //正确,若nullable为空
nullable?.length ?: -1
复制代码

2. 类型转换

as类型转换 跟java的类型转换同样,失败则抛异常 as?安全类型转换,转换失败返回null,不会抛异常数组

val stub:Childen = parent as Childen //转换失败 stub不会返回空,会抛异常
val stub:Childen = parent as? Childen //转换失败 stub 能够返回空
复制代码

3. 区间

ClosedRange的子类,IntRange最经常使用安全

  1. 半闭区间 ..
  2. 开区间 until
  3. 基本写法: 0..100 表示[0,100] 0 until 100 表示[0,100) i in 0..100 判断是否在区间[0,100]
val range:IntRange = 0..1024 //[0,1024]
val range_exclusive:IntRange = 0 until 1024 //[0,1024) = [0,1023]
val emptyRange:IntRange = 0...-1 //空区间
emptyRange.isEmpty() //判断区间是否为空
//迭代
for(i in range) 
复制代码

4. 数组

基本写法: val array:Array<类型> = arrayOf(类型的对象1,类型的对象2,.....) 基本操做: array[i] :输入第i个成员 array[i] = 新的类型对象 给第i个成员赋值bash

  • array.slice()截取 可传入区间 eg:0..10 或者 0 until 100
  • array.joinToString()转化成String 下面是对应的参数 -- separator: CharSequence:分隔符 默认为, --prefix: CharSequence: 增长前缀 默认为"" --postfix: CharSequence:增长后缀 默认为"" --limit: Int:截取位置(从1开始而不是从0开始) --truncated:被limit截取后,后面展现什么 --transform: 每一个元素进行处理返回处理后的数据

具体例子展现:ide

val arrayOfInt: IntArray = intArrayOf(1,3,5,7)
val arrayOfChar: CharArray = charArrayOf('H', 'e','l','l','o','W','o','r','l','d')
val arrayOfString: Array<String> = arrayOf("我", "是", "码农")
fun main() {
   System.out.println(arrayOfString.joinToString(""))
    var i:IntRange = 0..100
   System.out.println(arrayOfChar.slice(0..7))
   var array1 =  arrayOfString.joinToString("","前缀","后缀",2,"后面省略",transform = {
        //转换
        return@joinToString it+"转换"
    })
    var array2 =  arrayOfString.joinToString("","前缀","后缀",3,"后面省略",transform = {
        //转换
        return@joinToString it+"转换"
    })
   println(array1)
   println(array2)
}
-------------------------------------打印出来的log
我是码农
[H, e, l, l, o, W, o, r]
前缀我转换是转换后面省略后缀
前缀我转换是转换码农转换后缀
复制代码

5. 变量

val TAG = "str" 
并不等价与 java中的
public final String TAG = "str"
若是要等价的话
const val TAG = "str" 
复制代码

具体的能够看一下反编译val TAG = "str"的字节码跟public final String TAG = "str"有什么不一样~ 里面能够看到 val虽然不可赋值,可是它并非编译器常量,而是一个变量。也就是编译期并非替换成常量来进行的,因此后期仍是能够通过反射进行修改! 若是要像java中定义出编译期常量的话public final String TAG = "str"则须要使用到const这里反编译出来的跟java中的就相似了。函数

6. 函数与lamba表达式

  • 匿名函数写法

本质函数也是一个成员,只不过它是一段代码块post

val int2Long = fun(x:Int):Long{
  return x.toLong()
}
复制代码
  • Lambda表达式

本质:匿名函数 写法:{[参数列表]->[函数体,最后一行仍是返回值]} 举例:val sum = {a:Int,b:Int ->a+b} 调用: -- 用()进行调用 -- 等价于 invoke() -- eg: sum(1,2) 或者 sum.invoke(1,2) 简化: -- 函数参数参数调用是最后一位Lambda能够移出去 -- 函数参数只有一个Lambda,调用时小括号可省略 -- Lambda只有一个参数可默认为it -- 入参、返回值与形参一直的函数能够用函数引用的方式做为实参传入ui

示例一下:this

//首先 先看下Arrays里面的forEatch方法
public inline fun CharArray.forEach(action: (Char) -> Unit): Unit {
    for (element in this) action(element)
}
-------------------------------------------------
接下来,代码中调用
---------------------------------------------------
val arrayOfChar: CharArray = charArrayOf('H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd')
//最基本的调用,传入action的代码块
arrayOfChar.forEach(char ->{println(char)}) 
// 简化
//1. Lambda只有一个参数可默认为it
arrayOfChar.forEach ({println(it)})
// 2. 函数参数参数调用是最后一位Lambda能够移出去
arrayOfChar.forEach(){pritln(it)}
// 3. 函数参数只有一个Lambda,调用时小括号可省略
arrayOfChar.forEach{pritln(it)}
// 4. 入参、返回值与形参一致的函数能够用函数引用的方式做为实参传入
arrayOfChar.forEach(::println)

复制代码

7. 操做符

java不一样,kotlin的操做符容许咱们进行重载。重载的函数须要使用operation的修饰符标记 例子:spa

// 重写 减号的实例
class TestKotlin(var a:Int) {
    operator fun minus(i:Int):Int{
        return a - i
    }
}

fun main() {
    println(TestKotlin(6) - 5)
}
---------------------输入
1
复制代码

不少的操做符那些能够看一下 《Kotlin语言中文站》

8. 表达式(中缀 分支 when 等)

  • 中缀函数 只有一个参数,且用infix修饰的函数,使用时不须要对象.方法名(参数),直接 对象 方法名 参数
//定义
class Book { infix fun on(palce:String){...}}
//使用 
Book() on "My Name"
复制代码
  • 分支函数
  1. for 循环的in 把鼠标点击in可见其循环机制其实是iterator机制,hasNext()next(),判断有没有下一个值,有就获取
    in.png

下面咱们本身自定义一个MyIterator,跟MyIntList来演示一下

class MyIterator(val iterator:Iterator<Int>){
    operator fun next():Int{
        return iterator.next()
    }
    operator fun hasNext():Boolean{
        return iterator.hasNext()
    }
}

class MyIntList{
    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())
    }
}

fun main() {
    val list = MyIntList()
    list.add(1)
    list.add(2)
    list.add(3)
    for (i in list){
        println(i)
    }
}
复制代码

in.png
2. 跳过跟终止循环( continuebreak) 跟 java一致,跳过当前循环用 continue,终止循环用 break 3. 多层循环嵌套的终止结合标签使用

Outter@for(...){
  Inner@while(i<0){if(...)break@Outter}
}
复制代码

能够定义标签,对应关键字后面加上@标签,表明跳出到对应的某一层, 举个例子:

fun main() {
    val list = MyIntList()
    list.add(1)
    list.add(2)
    list.add(3)
    list.add(4)
    list.add(5)
//break到上一层
    for (i in list) {
        print(" $i")
        while (true) {
            print(" $i")
            break
        }
    }
    println(" ")
//break到制定标签
   OutSide@for (i in list) {
        print(" $i")
        while (true) {
            print(" $i")
                break@OutSide
        }
    }
}
---------------------打印---------------
 1 1 2 2 3 3 4 4 5 5 
 1 1
复制代码

if else 分支表达式等与java的不一样点,它们做为表达式,能够用来赋值,最后一个行的数据等于return的数据

fun compare():Int{
        val i = 10
        if (i == 10 ) 1 else 0
    }
复制代码

9. 异常捕获

java不一样的是,它也是表达式,最后一行的数据也是当成要返回的值。 可是 注意下面的写法:

return try{x/y}catch(e:Exception){0}finally{...}
复制代码

先执行完try有异常就跑到catch,最后finally的代码会执行,最后再返回值。(若是正常返回0,抛异常就返回x/y

10. 参数 (具名,变长,默认)

全部参数都有一点:若是传参时有歧义,须要使用具名参数

  • 默认参数
fun sum(arg1:Int = 3,arg2:Int = 2) = arg1+arg2
复制代码
  • 具名参数(vararg 变量名:类型)

给函数的实参附上形参

fun sum(arg1:Int,arg2:Int) = arg1+arg2
sum(arg1=2,arg2=3)
复制代码
  • 变长参数

某个参数能够接受多个值 与java不一样的是,它能够不用作最后一个参数,kotlin支持具名函数,因此它能够放在参数中任意位置。

fun hello (vararg ints:Int,string:String){ ints.forEach(::println)}
使用:
hello(1,2,3,4,string="Hello")
复制代码
  • Spread Operator(*变量名

应用场景: 只支持展开Array,只用于变长参数列表的实参,不能重载,不是必定意义上的运算符

fun hello (double:Double,vararg ints:Int,string:String){ ints.forEach(::println)}
使用:
val array = intArrayOf(1,2,3,4)
hello(3.0,*array,string="Hello")
复制代码
相关文章
相关标签/搜索