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

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")
}
主站蜘蛛池模板: 紫云| 安康市| 永仁县| 郴州市| 兰坪| 怀远县| 梁平县| 鹿泉市| 勐海县| 北宁市| 通城县| 新安县| 德兴市| 南部县| 新乡县| 浮山县| 札达县| 武宣县| 彭泽县| 隆昌县| 资源县| 浮梁县| 汝城县| 左云县| 师宗县| 洛扎县| 乐平市| 双峰县| 闵行区| 鄯善县| 府谷县| 开阳县| 鲁甸县| 汉沽区| 吉木萨尔县| 清镇市| 华蓥市| 泰顺县| 巴中市| 内黄县| 灯塔市|