简体   繁体   English

我可以限制只能使用原始类型和字符串调用泛型函数吗?

[英]Can I restrict a generic function to be called with primitive types and Strings only?

I have a function that assembles a URL with GET parameters, and it takes a parameter name of type String and currently a parameter value of type Any?我有一个用 GET 参数组合 URL 的函数,它采用String类型的参数名称和当前Any? on which it calls toString() if not null .如果不是null ,它会调用toString()

I want it to work only for types which can be meaningfully put into a URL (numbers, strings and booleans), and prevent people from calling it with any other object type.我希望它仅适用于可以有意义地放入 URL 的类型(数字、字符串和布尔值),并防止人们使用任何其他对象类型调用它。

Is this possible in Kotlin?这在 Kotlin 中可能吗?

The usecase is that I tend to forget converting units to numbers when calling this function, and end up with param=Angle(30,DEGREES) where I really want param=30 .用例是我在调用此函数时倾向于忘记将单位转换为数字,并最终得到我真正想要的 param param=Angle(30,DEGREES)param=30

If it is just a single function, you can use overloads for this:如果它只是一个函数,您可以为此使用重载:

private fun yourFunction(param: Any?){
    //your code
}

fun yourFunction(param: String?) = yourFunction(param as? Any?)
fun yourFunction(param: Int?) = yourFunction(param as? Any?)
fun yourFunction(param: Boolean?) = yourFunction(param as? Any?)
//the same for other types

At first, create your function with Any?首先,用Any?创建你的函数。 as you already do but make it private.就像您已经做的那样,但将其设为私有。

For every allowed type, add an overload with that type.对于每个允许的类型,添加该类型的重载。 That overload just calls the Any?那个重载只是调用Any? -overload. -超载。

If Union types are available in some future Kotlin version, you could use those as @ Tenfour04 mentioned in the comments of your question but Union types are not a Kotlin feature at the time of writing.如果在未来的 Kotlin 版本中提供联合类型,您可以使用问题评论中提到的 @ Tenfour04类型,但在撰写本文时联合类型不是 Kotlin 功能。

You can only have one upper bound for a generic type.泛型类型只能有一个上限。 Meaning that String OR Number is not possible as of time of writing.这意味着在撰写本文时, String OR Number是不可能的。

@dan1st pointed out that Union types may be the preferable solution to your problem. @dan1st 指出, 联合类型可能是解决您的问题的更好方法。

However you can use these attempt to solve your issue:但是,您可以使用这些尝试来解决您的问题:

  • Createing overloading method signatures where every type can be handled创建可以处理每种类型的重载方法签名

    fun makeUrl(path: String, parameter: String): MyUrl = downstreamUrlBuilder(path, parameter) fun makeUrl(path: String, parameter: Number): MyUrl = downstreamUrlBuilder(path, parameter.toString())
  • Creating a data access object that contains useful url information.创建一个包含有用 url 信息的数据访问对象。

     data class UrlParameter(val value: Any?) { init { if(value !is String && !is Number) throw IllegalArgumentException("reason") } } fun makeUrl(path: String, parameter: UrlParameter): MyUrl { TODO() }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM