schedule2019-06-28

【Kotlin】範囲判定の in start..end で実数を使えるか?

Kotlinで範囲内かどうか判定する in start..endがリファレンスでは整数の例だけ紹介されていた。 そこで、実数でも使えるか調べてみる。

先に結論を述べるが、実数のDoubleFloatでも使える。 ここにその例があるが、 この構文はrangeToと呼ばれているらしい?(上述のリファレンスではRanagesだった)。

環境

  • Kotlin 1.3

ブラウザ上で実行確認しました。

基本構文

1 以上かつ 10 以下はKotlinではi in 1..10と書けます。 これは1 <= i && i <= 10と同等に解釈されます。

if (i in 1..10) { // 1 <= i && i <= 10と同等
  println(i)
}

また、1 未満かつ 10 より大きいi !in 1..10と書けます。

println(5 in 1..10)    // true
println(0 in 1..10)    // false

// 逆
println(10 !in 1..10)   // false

この条件文の書き方が今まで覚えた言語と比べて新鮮でした。 大抵1 <= i && i <= 10みたいに長くなるので、便利ですね~。 1 <= i <= 10この書き方ができる言語も見た覚えがあるけど何だっけか。

実数と比較

リファレンスでは紹介されていなかった実数と比較も可能でした。

// 実数と比較
println(5.4 in 1..10)  // true

// Doubleの範囲内か
println(5.4 in 1.1..9.9)  // true

// Floatの範囲内か
println(5.4 in 1.1f..9.9f)  // true

この時、範囲の数値の型を合わせる必要があります。 異なっているとエラーが出ました。

println(3 in 1..4.1 ) // The floating-point literal does not conform to the expected type Int

val end: Double = 4.1
println(3 in 1..end ) // Type mismatch: inferred type is Double but Int was expected

Pythonのin range(n)との比較

Pythonに慣れていたため、Kotlinのこの書き方を疑ってました。 Python3のin range(n)では配列に含むかという意味です。 よって実数だとエラーになります。

# 0から9までの整数の中にあるか

print( 5 in range(10)) # True
print( 5.4 in range(10)) # False

print(list(range(10))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Kotlinでも配列に含むかは判定できます。

val list = listOf(1, 2, 3, 4, 5)
println(4 in list) // true

// 要素と型が違うとエラー
println(4.5 in list) // Type inference failed. The value of the type parameter T should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.

参考

普通にKotlinの範囲判定の記事として書けば良かったかも。