提问人:Alejandro Agüero 提问时间:3/25/2022 最后编辑:Alejandro Agüero 更新时间:3/25/2022 访问量:200
如何调用另一个函数的结果的特定命名参数?科特林
How to call specific named argument which is a result of another function? Kotlin
问:
为了调用 API,我从用户那里收集了两个值:
- 输入文本
- 一个默认字符串,它位于变量中,当用户在单选按钮组中选择筛选器时会发生变化。例如:“姓名”、“状态”、“性别”
获得这些值后,我需要调用下一个函数。
fun getCharacter(name: String? = null, status: String? = null, species: String? = null, type: String? = null, gender: String? = null) {
//code
}
我会手动调用,但我需要一种方法来指定命名参数,但需要指定它本身,因为它取决于用户选择的内容。viewModel.getCharacter(status = "alive")
有什么想法吗?
edit:最后,此函数调用由 retrofit 处理的挂起函数
@GET("character/")
suspend fun getCharacter(
@Query ("name") name: String?,
@Query("status") status: String?,
@Query("species") species: String?,
@Query("type") type: String?,
@Query("gender") gender: String?,
): CharacterResponse
答:
1赞
Tenfour04
3/25/2022
#1
按名称指定可选函数参数(使用反射)将非常困难。
相反,我将使用一个来表示这个 GET 请求,因此您可以将参数名称指定为函数参数:@QueryMap
@GET("character/")
suspend fun getCharacter(
@QueryMap params: Map<String, String>
): CharacterResponse
suspend fun getCharacter(paramName: String, paramValue: String): CharacterResponse {
// ...
return service.getCharacter(mapOf(paramName to paramValue))
}
viewModel.getCharacter("status", "alive")
1赞
cactustictacs
3/25/2022
#2
您是否尝试调用函数并使用默认值,但提供在运行时决定的默认值之一?据我所知,不幸的是,你不能这样做——我自己也遇到了这个限制
老实说,对于你正在做的事情,我不会使用默认参数 - 你基本上有某种类型的过滤器,以及它的一些值,对吧?我只是把它传递到你的函数中:
// I'm not entirely sure what string data you're passing but hopefully this
// makes enough sense that you can work out how to apply it to your thing
data class Filter(val type: FilterType, val value: String = type.defaultString)
enum class FilterType(val defaultString: String) {
NAME("name"), STATUS("alive")
}
fun getCharacter(filter: Filter) {
// do the thing
}
这样做的好处是,因为你在枚举中定义了所有选项,你的单选按钮也可以在内部使用该枚举 - 你可以将显示文本作为属性放在枚举上,并将其用作 UI 中的标签,但你实际上是在使用并传递一个可以直接使用的, 而不是需要转换为类型或属性引用的字符串。FilterType
如果你愿意,你也可以做一个列表,以防你想实现多个过滤器!getCharacter
Filter
0赞
lukas.j
3/25/2022
#3
使用反射:
import kotlin.reflect.KParameter.Kind.INSTANCE
import kotlin.reflect.full.memberFunctions
fun callFunction(instance: Any, functionName: String, arguments: Map<String, String?>) {
val function = instance::class.memberFunctions.first { it.name == functionName }
function.callBy(function.parameters.associateWith { if (it.kind == INSTANCE) instance else arguments[it.name] })
}
class ViewModel {
fun getCharacter(name: String? = null, status: String? = null, species: String? = null, type: String? = null, gender: String? = null) {
println("name: $name")
println("status: $status")
println("species: $species")
println("type: $type")
println("gender: $gender")
}
}
val viewModel = ViewModel()
callFunction(viewModel, "getCharacter", mapOf("species" to "animal", "type" to "mammal"))
输出:
name: null
status: null
species: animal
type: mammal
gender: null
评论