我有一个when
构造,想要在两件事上匹配:
when (activeRequest.verb to activeRequest.resourceType) {
GET to "all" -> allGet()
PUT to "foo" -> fooPut()
GET to "foo" -> fooGet()
POST to "bar" -> barPost()
GET to "bar" -> barGet()
COPY to "bar" -> barCopy()
DELETE to "bar" -> barDelete()
else -> logMismatch()
}
使用to
对构造函数是唯一的方法吗?配对似乎很奇怪(尽管它可以工作)。我很难找到它,因为类似
for ((key, value) in hashMap) {
println("$key $value)
}
使我感到很高兴,我应该能够在when
代码中执行类似的操作,例如
when (activeRequest.verb, activeRequest.resourceType) {
(GET, "all") -> allGet()
(PUT, "foo") -> fooPut()
...
else -> logMismatch()
}
这对眼镜有用吗...如果我想做3件怎么办?
答案 0 :(得分:3)
循环示例中的语法是destructuring declaration,它基本上是一种语法糖,用于在一行中声明对一个对象的多个成员变量的引用。它不会反过来,因为Kotlin没有用于任意元组的机制。
我无法真正提出一种美观的方法来使用两个以上的变量。我想到的选择是使用基本上像这样的元组工作的enum:
enum class Response(val verb: String, val type: String) {
GET_FOO("GET", "foo"),
...
INVALID("?", "?");
companion object {
fun from(verb: String, type: String): Response {
for(response in values()) {
if(response.verb == verb && response.type == type)
return response
}
return INVALID
}
}
}
when(Response.from(activeRequest.verb, activeRequest.resourceType)) {
GET_FOO -> getFoo()
...
}
或者使用数组。不幸的是,Kotlin数组的相等性不是按内容排列的,因此最终会产生很多样板,并且when
语法看起来也非常好。 (我添加了扩展功能使它更好一些,但我仍然不喜欢它):
fun Array<*>.whenCheat(vararg others: Any?): Boolean {
return this contentEquals others
}
val array = arrayOf("GET", "foo")
when {
array.whenCheat("GET", "foo") -> getFoo()
...
}
我怀疑,通过对功能的响应图可以更好地解决这类问题。希望其他人会提供更聪明的解决方案。
答案 1 :(得分:1)
另一种替代方法是使用data class
。例如:
data class Response(val verb: String, val type: String, val other: Int)
// This is an example of what the functions could be... edit as needed
val all = { _: Response -> "all"}
val some = { _: Response -> "some"}
val unknown = { _: Response -> "unknown"}
val handlers = mapOf<Response, (Response) -> String>(
Response("GET", "all", 200) to all,
Response("GET", "some", 400) to some
// and all your other mappings
)
然后,您可以使用该地图,例如:
val myFun = handlers.getOrDefault(myResponse, unknown)
答案 2 :(得分:0)
我想做3件物品怎么办?
使用Triple
代替Pair
答案 3 :(得分:0)
如果您只是将数据捆绑到一个类中并覆盖其when
方法,则可以将equals
与任意数量的项一起使用:
class Person(
var firstName: String = "",
var lastName: String = "",
var age: Int = 0,
var rate: Int = 0) {
override fun equals(other: Any?): Boolean {
val otherPerson = other as Person
return (
firstName.equals(otherPerson.firstName) &&
lastName.equals(otherPerson.lastName) &&
age.equals(otherPerson.age) &&
rate.equals(otherPerson.rate))
}
// just to avoid warning
override fun hashCode(): Int {
return super.hashCode()
}
}
fun main(args: Array < String > ) {
val p = Person("John", "Doe", 18, 2)
when (p) {
Person("Nick", "Doe", 18, 2) -> println("found at 1")
Person("John", "Doe", 18, 2) -> println("found at 2")
Person("Maria", "Doe", 18, 2) -> println("found at 3")
else -> println("not found")
}
}