Kevin Learn Kotlin:空指针检查

Posted Kevin_小飞象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kevin Learn Kotlin:空指针检查相关的知识,希望对你有一定的参考价值。

可空类型

当我们在声明方法时,如果允许在这个方法被调用的时候传给它 null 的实参,则需要显示地 在类型名称后面加上问号来标记它:

fun learn(s: String?): Int =

问号可以加在任何类型的后面来表示这个类型的变量可以存储 null 引用,而所有常见类型默认都是非空的,除非显示地把它标记为可空。
当你有一个可空类型的值,对它的操作也会受到限制:

  • 不能调用它的方法
  • 不能把它赋值给非空类型的变量
  • 不能把可空类型的值传给拥有非空类型参数的函数
fun learn(s: String): Int =
    if (s != null) s.length else 0

判空辅助工具

1. 安全调用运算符 “?.”

处理可空对象
安全调用运算符 ?. 把一次 null 检查和一次方法调用合并成一个操作。

fun main() 
    printAllCaps("Kevin")
    printAllCaps(null)


fun printAllCaps(s: String?) 
    val allCaps: String? = s?.toUpperCase()
    println(allCaps)

运行结果:

KEVIN
null

处理可空属性
安全调用不光可以调用方法,也能访问属性:

class Employee(val name: String, val manager:Employee?)

fun main() 
    val ceo = Employee("Da Boss",null)
    val developer = Employee("Kevin",ceo)

    println(managerName(developer))
    println(managerName(ceo))


fun managerName(employee: Employee) : String? = employee.manager?.name

运行结果:

Da Boss
null

2. Elvis 运算符 “?:”

Kotlin 有方便的运算符来提供代替 null 的默认值,它被称作 Elvis 运算符,我们在 2.3 的基础上增加红框内的代码,使得 name 为空的时候将返回值设为 UnKnow:

class Employee(val name: String, val manager:Employee?)

fun main() 
    val ceo = Employee("Da Boss",null)
    val developer = Employee("Kevin",ceo)

    println(managerName(developer))
    println(managerName(ceo))


fun managerName(employee: Employee) : String? = 
employee.manager?.name ?:"UnKnow"

运行结果:

Da Boss
UnKnow

3. 安全转换 “:as ?”

安全转换运算符会尝试把值转换成指定的类型,如果类型不合适就返回 null

data class Person(val name: String,val age: Int)

fun main() 
    val person = Person("Kevin",18)
    val person2 = Person("Kevin",25)

    println(person2.comparePerson(person))



fun Person.comparePerson(other : Any ?) : Boolean 
    val otherPerson = other as? Person ?: return false
    return name == otherPerson.name

输出结果:

true

4. 非空断言 “!!”

非空断言 是 Kotlin 提供给你的最简单直率的处理可空类型的工具,它使用 !! 表示,可以把任何值转换成非空类型。

class HomeFragment : Fragment(R.layout.fragment_home) 

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)

        rv_fruit.layoutManager = LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false)
        rv_fruit.adapter = MyAdapter()
    

    inner class MyAdapter : RecyclerView.Adapter<MyViewHolder>()
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder 
            val itemView = LayoutInflater.from(context)
                .inflate(R.layout.item_fruit,parent,false)
            return MyViewHolder(itemView)
        

        override fun onBindViewHolder(holder: MyViewHolder, position: Int) 
            // kotlin 三种方式加载图片资源
            holder.itemView.iv_fruit.setImageResource(R.mipmap.ic_apple)
            // context!! 表示context 不为null
            holder.itemView.iv_fruit.setImageDrawable(
                ContextCompat.getDrawable(
                    context!!,
                    R.mipmap.ic_apple
                )
            )
        

        override fun getItemCount(): Int 
            return 20
        

    

    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) 

5. let 函数

当可空参数最常见的一种用法就是被传递给一个接收非空参数的函数之前,需要进行相应的检查。

fun main() 
    val nullEmail: String ? = "nullEmail"
    nullEmail?.let  send(nullEmail) 


fun send(email: String) 
    println("sending email to $email")

let 函数只在 nullEmail 的值非空时才被调用,所以就能在 lambda 中把 nullEmail 当做非空的实参来使用。

以上是关于Kevin Learn Kotlin:空指针检查的主要内容,如果未能解决你的问题,请参考以下文章

Kevin Learn Kotlin:委托

Kevin Learn Kotlin-->Kotlin 知识梳理

Kevin Learn Kotlin:泛型

Kevin Learn Kotlin:案例四则运算

Kevin Learn Kotlin-->Kotlin 学习资料

Kevin Learn Kotlin:类对象和接口