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

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")
}
主站蜘蛛池模板: 来凤县| 靖州| 乳源| 芒康县| 溧水县| 沐川县| 曲麻莱县| 赣榆县| 沂南县| 利津县| 普格县| 青海省| 高雄县| 哈尔滨市| 西盟| 两当县| 和政县| 罗甸县| 六枝特区| 大兴区| 淮安市| 济阳县| 怀来县| 资溪县| 安溪县| 苏尼特右旗| 廉江市| 宜黄县| 泽库县| 湖南省| 逊克县| 普格县| 乌兰浩特市| 阿克陶县| 丽水市| 广南县| 锡林郭勒盟| 井研县| 屯留县| 岳阳市| 库尔勒市|