SubwayTooter-Android-App/app/src/test/java/jp/juggler/subwaytooter/TestKotlinFeature.kt

269 lines
7.3 KiB
Kotlin
Raw Normal View History

package jp.juggler.subwaytooter
2024-03-17 11:05:30 +01:00
import kotlin.test.Test
2018-01-11 10:31:25 +01:00
//import kotlin.test.*
typealias TestLambdaCallback = (x: Int) -> Int
2024-03-17 11:05:30 +01:00
@Suppress(
"unused", "UNUSED_VARIABLE",
"UNUSED_VALUE", "ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE",
"ReplaceCallWithComparison"
)
class TestKotlinFeature {
private val CODE_A = 1
private val CODE_A2 = 2
// コンパイラに予測できない方法でIntの10を生成する
private fun generate10A(): Int {
return ("1" + "0").toInt()
}
// コンパイラに予測できない方法でIntの10を生成する
private fun generate10B(): Int {
var i = 0
while (true) {
++i
if (i % 5 == 0 && i % 2 == 0) return i
}
}
interface MyKotlinInterface {
fun method(x: Int): Int
}
@Test
fun testLambda() {
// 定義例(文脈あり)
println(10.let { x -> x * x })
println(10)
// 定義例(文脈不明)
val a = { println("testLambda") }
// 参照型の定義
val ref: (x: Int) -> Int = { it * it }
// 参照型の呼び出し
println(ref(10))
// 参照型の定義(Nullable)
@Suppress("RedundantNullableReturnType")
val refNullable: TestLambdaCallback? = { it * it }
if (refNullable != null) {
refNullable(10)
}
}
@Test
fun testAnonymousFunction() {
// 定義例(文脈あり)
println(10.let(fun(x: Int) = x * x))
println(10)
// 定義例(文脈不明)
val a = fun(x: Int) = x * x
// 参照型の定義
val ref: (x: Int) -> Int = a
// 参照型の呼び出し
println(ref(10))
// 参照型の定義(Nullable)
@Suppress("RedundantNullableReturnType")
val refNullable: TestLambdaCallback? = fun(i: Int) = i * i
if (refNullable != null) {
refNullable(10)
}
}
@Test
fun testObjectExpression() {
// 定義例(文脈あり)
@Suppress("UnnecessaryAbstractClass")
abstract class Base {
abstract fun method(x: Int): Int
}
val a = object : Base() {
override fun method(x: Int): Int {
return x * x
}
}
// 定義例(文脈の有無で変化しない)
// 参照型の定義
val ref: Base = a
// 参照型の定義(Nullable)
@Suppress("RedundantNullableReturnType")
val refNullable: Base? = a
if (refNullable != null) {
val v = refNullable.method(10)
println("OE v=$v")
}
fun caller(b: Base) {
val v = b.method(10)
println("OE b $v")
}
caller(object : Base() {
override fun method(x: Int): Int {
return x * x * x
}
})
}
private fun member(x: Int) = x * x
@Test
fun testMemberReference() {
fun caller(a: (receiver: TestKotlinFeature, x: Int) -> Int) {
val v = a(this, 10)
println("testMemberReference caller $v")
}
caller(TestKotlinFeature::member)
val b = TestKotlinFeature::member
val a: (receiver: TestKotlinFeature, x: Int) -> Int = TestKotlinFeature::member
}
fun methodNotInline(callback: (x: Int) -> Int): Int {
return callback(3)
}
inline fun methodInline(callback: (x: Int) -> Int): Int {
return callback(5)
}
@Test
fun testReturn() {
// loop@ for( i in 1..2) {
// // 関数の引数以外の場所で定義したラムダ式
// var x = { x : Int ->
// break // コンパイルエラー
// break@loop // コンパイルエラー
// // return // コンパイルエラー
// x * x
// }(10)
// println("testReturn A:$x")
//
// // 非インライン関数の引数として定義したラムダ式
// x = methodNotInline { x : Int ->
// break // コンパイルエラー
// break@loop // コンパイルエラー
//
// // return // コンパイルエラー
//
// return@methodNotInline x * x
// }
// println("testReturn B:$x")
//
// // インライン関数の引数として定義したラムダ式
// methodInline { x : Int ->
// break // コンパイルエラー
// break@loop // コンパイルエラー
//
// return 10 // できる
//
// return@methodInline 10 // できる
// }
// }
}
private fun <A, B> A.letNotInline(code: (A) -> B): B {
return code(this)
}
@Test
fun testInline0() {
var result: Int
val n = 11
for (i in 1..10) {
println(n.letNotInline { v ->
val rv = v * i
result = rv
rv
})
}
}
@Test
fun testInline1() {
var result: Int
val n = 12
for (i in 1..10) {
println(n.let { v ->
val rv = v * i
result = rv
rv
})
}
}
@Test
fun testInline2() {
var result: Int
val n = 13
for (i in 1..10) {
val rv = n * i
result = rv
println(rv)
}
}
@Test
fun testRawArray() {
// サイズを指定して生成
val a = IntArray(4)
for (i in a.indices) {
a[i] = i * 2
}
println(a.joinToString(","))
// サイズと初期化ラムダを指定して生成
val b = IntArray(4) { index -> index * 3 }
println(b.joinToString(","))
// 可変長引数で初期化するライブラリ関数
val b2 = intArrayOf(0, 1, 2, 3)
// 参照型の配列だと初期化ラムダが必須
val c = Array<CharSequence>(4) { (it * 4).toString() }
println(c.joinToString(","))
val d = Array<CharSequence?>(4) { if (it % 2 == 0) null else (it * 5).toString() }
println(d.joinToString(","))
// ラムダ式の戻り値の型から配列の型パラメータが推測される
val e = Array(4) { if (it % 2 == 0) null else (it * 6).toString() }
println(e.joinToString(","))
// 可変長引数で初期化するライブラリ関数
val e2 = arrayOf(null, 1, null, 2)
}
@Test
fun testOutProjectedType() {
fun foo(args: Array<out Number>) {
val sb = StringBuilder()
for (s in args) {
if (sb.isNotEmpty()) sb.append(',')
sb
.append(s.toString())
.append('#')
.append(s.javaClass.simpleName)
}
println(sb)
println(args.contains(6)) // 禁止されていない。inポジションって何だ…
// args[0]=6 //禁止されている
}
foo(arrayOf(1, 2, 3))
foo(arrayOf(1f, 2f, 3f))
}
}