如何调用作为另一个函数结果的特定命名参数?科特林
How to call specific named argument which is a result of another function? Kotlin
为了调用 API,我从用户那里收集了两个值:
- 输入文字
- 一个默认字符串,它存在于变量中并在用户 select 无线电组中的过滤器时发生变化。例如:“姓名”、“身份”、“性别”
获得这些值后,我需要调用下一个函数。
fun getCharacter(name: String? = null, status: String? = null, species: String? = null, type: String? = null, gender: String? = null) {
//code
}
我会手动调用 viewModel.getCharacter(status = "alive")
但我需要一种方法来指定命名参数本身,因为它取决于用户 selected.
有什么想法吗?
编辑:最后这个函数调用了一个由 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
很难通过名称指定可选函数参数(使用反射)。
相反,我会为此 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")
您是否尝试调用该函数并使用默认值,但提供其中一个在 运行 时决定的值?据我所知,不幸的是你不能那样做 - 我自己 运行 遇到了这个限制
老实说,对于您正在做的事情,我不会使用默认参数 - 您基本上有某种类型的过滤器,并且有一些价值,对吧?我只是将其传递到您的函数中:
// 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
的列表,以防您想要实施多个过滤器!
使用反射:
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
为了调用 API,我从用户那里收集了两个值:
- 输入文字
- 一个默认字符串,它存在于变量中并在用户 select 无线电组中的过滤器时发生变化。例如:“姓名”、“身份”、“性别”
获得这些值后,我需要调用下一个函数。
fun getCharacter(name: String? = null, status: String? = null, species: String? = null, type: String? = null, gender: String? = null) {
//code
}
我会手动调用 viewModel.getCharacter(status = "alive")
但我需要一种方法来指定命名参数本身,因为它取决于用户 selected.
有什么想法吗?
编辑:最后这个函数调用了一个由 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
很难通过名称指定可选函数参数(使用反射)。
相反,我会为此 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")
您是否尝试调用该函数并使用默认值,但提供其中一个在 运行 时决定的值?据我所知,不幸的是你不能那样做 - 我自己 运行 遇到了这个限制
老实说,对于您正在做的事情,我不会使用默认参数 - 您基本上有某种类型的过滤器,并且有一些价值,对吧?我只是将其传递到您的函数中:
// 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
的列表,以防您想要实施多个过滤器!
使用反射:
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