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

When (value)

The simplest example of when is matching against different constants, which will be similar to the typical usage of switch in a language such as Java:

    fun whatNumber(x: Int) { 
      when (x) { 
        0 -> println("x is zero") 
        1 -> println("x is 1") 
        else -> println("X is neither 0 or 1") 
      } 
    } 

Note that when must be exhaustive, and so the compile enforces that the final branch is an else statement.

If the compiler can infer that all possible conditions have been satisfied, then the else can be omitted. This is common with sealed classes or enums—more on those in future chapters.

Similar to if...else and try..catch, when can be used as an expression, and so the result of the evaluated branch is the result that is returned. In this example, the when expression is assigned to the val isZero before being returned:

    fun isMinOrMax(x: Int): Boolean { 
      val isZero = when (x) { 
        Int.MIN_VALUE -> true 
        Int.MAX_VALUE -> true 
        else -> false 
      } 
      return isZero 
    } 

Furthermore, constants can be combined together if the branch code is the same. To do this, we simply use a comma to separate constants:

    fun isZeroOrOne(x: Int): Boolean { 
      return when (x) { 
        0, 1 -> true 
        else -> false 
      } 
    } 

Note that, in this example, the 0 and 1 clauses were combined together and the return value was directly returned instead of being assigned to an intermediate variable.

We are not just restricted to matching constants in each condition. We can use any function that returns the same type as the type being matched. The function is invoked, and if the result matches the value, then that branch is evaluated:

    fun isAbs(x: Int): Boolean { 
      return when (x) { 
        Math.abs(x) -> true 
        else -> false 
      } 
    } 

In the example, the Math.abs function is invoked, and if the result is the same as the input value, then the value was already absolute, so true is returned. Otherwise, the result of Math.abs must have been different, and so the value was not absolute and false is returned.

Ranges are also supported. We can use the in operator to verify whether the value is included in the range, and if so, the condition is evaluated to true:

    fun isSingleDigit(x: Int): Boolean { 
      return when (x) { 
        in -9..9 -> true 
        else -> false 
      } 
    } 

Note that if the value is contained in the interval (-9, 9), then it must be a single digit, and so true is returned; otherwise, false is returned.

Along a similar line, we can use in to verify whether the value is contained in a collection:

    fun isDieNumber(x: Int): Boolean { 
      return when (x) { 
        in listOf(1, 2, 3, 4, 5, 6) -> true 
        else -> false 
      } 
    } 

Finally, when can also use smart casts. As discussed previously, smart casts allow the compiler to verify the runtime type of a variable, and expose it:

    fun startsWithFoo(any: Any): Boolean { 
      return when (any) { 
        is String -> any.startsWith("Foo") 
        else -> false 
      } 
    } 

In the previous example, the parameter is declared with a type of Any, so that there is no restriction on what type can be passed as an argument (analogous to Java's object type). Inside the when expression, we check whether the type is a string, and if it is, we can then access functions declared on the string, such as the startsWith function.

There is no restriction on combining these different condition types. You can happily mix smart casts, in, arbitrary functions, and constants, all in the same when expression.

Since Kotlin 1.3, the when expression has allowed you to capture the subject into a variable.  And this variable's scope is restricted to the body of  when .  Here is an example handling the HTTP response code while capturing it in the statusCode variable:

when (val statusCode = response.statusCode) {
in 200..204 -> println("Success: $statusCode")
in 400..451 -> println("Client Error: $statusCode")
else -> println("Unknown HTTP status code")
}
主站蜘蛛池模板: 长治市| 三门峡市| 南康市| 秦皇岛市| 乌拉特前旗| 永兴县| 仪征市| 玛曲县| 沅江市| 新巴尔虎右旗| 资溪县| 北票市| 碌曲县| 监利县| 准格尔旗| 神木县| 钦州市| 都昌县| 英超| 清水河县| 榕江县| 运城市| 云安县| 木兰县| 六盘水市| 休宁县| 荣昌县| 紫云| 涿州市| 新乡市| 前郭尔| 浑源县| 峨山| 和田市| 安龙县| 曲麻莱县| 河西区| 汽车| 合作市| 静宁县| 稷山县|