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

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")
}
主站蜘蛛池模板: 田东县| 扎兰屯市| 托克托县| 绥芬河市| 林西县| 海原县| 乌审旗| 宾阳县| 延津县| 兴和县| 蓬安县| 庆元县| 黎城县| 论坛| 宾川县| 修水县| 晋宁县| 赣州市| 金堂县| 南开区| 环江| 新邵县| 东丽区| 东港市| 湘潭县| 怀集县| 红河县| 正镶白旗| 呼玛县| 余江县| 玉环县| 舟山市| 阿城市| 松江区| 介休市| 枞阳县| 固阳县| 化德县| 静宁县| 佛坪县| 丹棱县|