官术网_书友最值得收藏!

Non-nullable smart cast

Smart casts also handle other cases, including nullity checks. Let's assume that we have a view variable that is marked as nullable, because we don't know whether or not findViewById will return a view or null:

val view: View? = findViewById(R.layout.activity_shop) 

We could use the safe call operator to access view methods and properties, but in some cases we may want to perform more operations on the same object. In these situations, smart casting may be a better solution:

    val view: View? 
 
    if ( view != null ){ 
        view.isShown() 
// view is casted to non-nullable inside if code block } view.isShown() // error, outside if the block view is nullable

When performing null checks like this, the compiler automatically casts a nullable view (View?) to non-nullable (View). This is why we can call the isShown method inside the if block, without using a safe call operator. Outside the if block, the view is still nullable.

Each smart cast works only with read-only variables, because a read-write variable may change between the time the check was performed and the time the variable is accessed.

Smart casts also work with a function's return statements. If we perform nullity checks inside the function with a return statement, then the variable will also be cast to non-nullable:

    fun setView(view: View?){
if (view == null)
return
//view is casted to non-nullable
view.isShown()
}

In this case, Kotlin is absolutely sure that the variable value will not be null, because the function would call return otherwise. Functions will be discussed in more detail in Chapter 3, Playing with Functions. We can make the preceding syntax even simpler by using the Elvis operator and performing a nullity check in a single line:

    fun verifyView(view: View?){ 
        view ?: return 
 
        //view is casted to non-nullable 
        view.isShown() 
        //.. 
    } 

Instead of just returning from the function, we may want to be more explicit about the existing problem and throw an exception. Then we can use the Elvis operator together with the error throw:

    fun setView(view: View?){ 
        view ?: throw RuntimeException("View is empty") 
  
        //view is casted to non-nullable 
        view.isShown() 
    } 

As we can see, smart casts are a very powerful mechanism that allows us to decrease the number of nullity checks. This is why they are heavily exploited by Kotlin. Remember the general rule--smart casts work only if Kotlin is absolutely sure that the variable cannot be changed after the cast, even by another thread.

主站蜘蛛池模板: 涡阳县| 南木林县| 鄯善县| 华坪县| 奇台县| 沙河市| 侯马市| 浙江省| 铜鼓县| 邓州市| 潜山县| 嘉善县| 七台河市| 阳新县| 烟台市| 衡阳市| 龙里县| 涪陵区| 靖安县| 寿宁县| 柏乡县| 石首市| 松原市| 屏东县| 瑞昌市| 通辽市| 汨罗市| 东乌珠穆沁旗| 永城市| 邯郸市| 贵阳市| 时尚| 泰来县| 民权县| 蓬溪县| 女性| 泗水县| 海原县| 偏关县| 天长市| 阜阳市|