You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何简洁遍历所有布尔值测试多参布尔函数?

问题描述

我有一个如下的Kotlin函数:

fun foo(a: Boolean, b: Boolean, c: Boolean) { /*...*/ }

我想要用所有可能的参数值来测试它,最初尝试使用范围遍历:

for (a in false..true)
    for (b in false..true)
        for (c in false..true) {
            val expected = ...
            assertThat(foo(a, b, c)).isEqualTo(expected)
        }

但遗憾的是Kotlin并没有BooleanRange类型。

我改用以下方式实现:

for (a in 0..1)
    for (b in 0..1)
        for (c in 0..1) {
            val expected = ...
            assertThat(foo(a == 1, b == 1, c == 1)).isEqualTo(expected)
        }

但这种方式不够直观。

我还试过:

for (a in arrayOf(false, true))
    for (b in arrayOf(false, true))
        for (c in arrayOf(false, true)) {
            val expected = ...
            assertThat(foo(a, b, c)).isEqualTo(expected)
        }

但这仍然太过冗长。请问有没有更简洁的方法?比如Kotlin是否有直接遍历false和true这两个值的函数?我注意到有BooleanIterator类型,但不确定是否能用在这里。


简洁实现方案

1. 复用布尔值列表常量

先定义一个包含所有布尔值的常量列表,后续循环直接复用,避免重复代码:

val booleans = listOf(false, true)

for (a in booleans)
    for (b in booleans)
        for (c in booleans) {
            val expected = ...
            assertThat(foo(a, b, c)).isEqualTo(expected)
        }

2. 内联使用轻量序列

用sequenceOf替代arrayOf,语法更简洁且是惰性求值,性能更优:

for (a in sequenceOf(false, true))
    for (b in sequenceOf(false, true))
        for (c in sequenceOf(false, true)) {
            val expected = ...
            assertThat(foo(a, b, c)).isEqualTo(expected)
        }

3. 扩展布尔类型实现范围遍历

自己实现rangeTo扩展函数,让你最初设想的false..true语法直接生效:

operator fun Boolean.rangeTo(other: Boolean): Iterable<Boolean> {
    return if (this == other) listOf(this) else listOf(false, true)
}

之后就能像最开始尝试的那样使用范围遍历:

for (a in false..true)
    for (b in false..true)
        for (c in false..true) {
            val expected = ...
            assertThat(foo(a, b, c)).isEqualTo(expected)
        }

4. 笛卡尔积处理多参数场景

如果参数数量超过3个,嵌套循环会变得非常繁琐,这时可以用笛卡尔积函数扁平化处理所有参数组合:

fun <T> cartesianProduct(vararg lists: List<T>): List<List<T>> {
    return lists.fold(listOf(listOf())) { acc, list ->
        acc.flatMap { accList -> list.map { accList + it } }
    }
}

调用时传入布尔值列表,直接遍历生成的所有组合:

val booleans = listOf(false, true)
cartesianProduct(booleans, booleans, booleans).forEach { (a, b, c) ->
    val expected = ...
    assertThat(foo(a, b, c)).isEqualTo(expected)
}

内容的提问来源于stack exchange,提问作者k314159

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:25:34