Kotlin 通用接口解析器
Kotlin generic interface resolver
我正在尝试构建一个解析器,给定一些域上下文 return 支持通用接口的实现。代码如下(域抽象):
interface Interface<T>
class StringImplementation: Interface<String>
class BooleanImplementation: Interface<Boolean>
class Resolver {
fun <T : Any> resolve(implementation: String): Interface<T> {
return when (implementation) {
"string" -> StringImplementation()
"boolean" -> BooleanImplementation()
else -> throw IllegalArgumentException()
}
}
}
这段代码看起来不错,但编译器在抱怨,因为第 11 行 Type missmatch: Required: Interface<T> Found: StringImplementation
和第 12 行 Type missmatch: Required: Interface<T> Found: BooleanImplementation
。
为什么这是个问题?我虽然在方法合同中设置 <T : Any>
将允许 return 任何类型的实现。这里的约束是方法resolve
的return类型必须是Interface<T>
,换成Interface<*>
会让编译器闭嘴,但这不是我们需要的。
TL;DR
一个函数只能有 1 种 return 类型,但是你的函数有 2 种不同的 return 类型。
只有这个行得通:
interface Interface<T>
class StringImplementation: Interface<String>
class BooleanImplementation: Interface<Boolean>
class Resolver {
fun resolve(implementation: String): Interface<*> { // <-- star
return when (implementation) {
"string" -> StringImplementation()
"boolean" -> BooleanImplementation()
else -> throw IllegalArgumentException()
}
}
}
说明
从函数定义的角度来看,它必须有明确的、明确的return类型。 Interface<T>
说应该是扩展 Interface
和 explicit 类型 T
具体实现可以在开头知道函数的执行。
当您调用 resolve
时,您的代码无法知道 T
会是什么。您还能如何想象该函数会 return 返回什么?!
缩短:一个函数可以恰好有 1 种 return 类型,但是你的函数有 2 种不同的 return 类型(Interface<String>
/ Interface<Boolean>
)。
Continue to read here 如果您想深入研究泛型并获得更技术性的描述。
编译器不知道 T
是否匹配 implementation
变量。即使 implementation
是 string
,T
也可能是 String
的另一种类型。因此,您可以像@Neo 提到的那样擦除通用类型,或者您需要转换 return 类型。
interface Interface<T>
class StringImplementation: Interface<String>
class BooleanImplementation: Interface<Boolean>
class Resolver {
inline fun <reified T : Any> resolve(): Interface<T> {
return when (T::class) {
String::class -> StringImplementation() as Interface<T>
Boolean::class -> BooleanImplementation() as Interface<T>
else -> throw IllegalArgumentException()
}
}
}
要获得更高的类型安全性,您可以使用具体化参数并使用它来解析类型。 (注意演员表还是有必要的)
I though setting <T : Any>
in the method contract would allow to return an implementation of any type.
不,这意味着它具有到return任何类型的实现调用者要求。例如,在 Animesh Sahu 的示例中,resolve<Boolean>("string")
必须 return 和 Interface<Boolean>
,但是您对 resolve
的实现将 return 和 StringImplementation
。当然也可以是resolve<File>("string")
等
allow to return an implementation of any type
被调用的方法选择的恰好是Interface<*>
。
我正在尝试构建一个解析器,给定一些域上下文 return 支持通用接口的实现。代码如下(域抽象):
interface Interface<T>
class StringImplementation: Interface<String>
class BooleanImplementation: Interface<Boolean>
class Resolver {
fun <T : Any> resolve(implementation: String): Interface<T> {
return when (implementation) {
"string" -> StringImplementation()
"boolean" -> BooleanImplementation()
else -> throw IllegalArgumentException()
}
}
}
这段代码看起来不错,但编译器在抱怨,因为第 11 行 Type missmatch: Required: Interface<T> Found: StringImplementation
和第 12 行 Type missmatch: Required: Interface<T> Found: BooleanImplementation
。
为什么这是个问题?我虽然在方法合同中设置 <T : Any>
将允许 return 任何类型的实现。这里的约束是方法resolve
的return类型必须是Interface<T>
,换成Interface<*>
会让编译器闭嘴,但这不是我们需要的。
TL;DR
一个函数只能有 1 种 return 类型,但是你的函数有 2 种不同的 return 类型。
只有这个行得通:
interface Interface<T>
class StringImplementation: Interface<String>
class BooleanImplementation: Interface<Boolean>
class Resolver {
fun resolve(implementation: String): Interface<*> { // <-- star
return when (implementation) {
"string" -> StringImplementation()
"boolean" -> BooleanImplementation()
else -> throw IllegalArgumentException()
}
}
}
说明
从函数定义的角度来看,它必须有明确的、明确的return类型。 Interface<T>
说应该是扩展 Interface
和 explicit 类型 T
具体实现可以在开头知道函数的执行。
当您调用 resolve
时,您的代码无法知道 T
会是什么。您还能如何想象该函数会 return 返回什么?!
缩短:一个函数可以恰好有 1 种 return 类型,但是你的函数有 2 种不同的 return 类型(Interface<String>
/ Interface<Boolean>
)。
Continue to read here 如果您想深入研究泛型并获得更技术性的描述。
编译器不知道 T
是否匹配 implementation
变量。即使 implementation
是 string
,T
也可能是 String
的另一种类型。因此,您可以像@Neo 提到的那样擦除通用类型,或者您需要转换 return 类型。
interface Interface<T>
class StringImplementation: Interface<String>
class BooleanImplementation: Interface<Boolean>
class Resolver {
inline fun <reified T : Any> resolve(): Interface<T> {
return when (T::class) {
String::class -> StringImplementation() as Interface<T>
Boolean::class -> BooleanImplementation() as Interface<T>
else -> throw IllegalArgumentException()
}
}
}
要获得更高的类型安全性,您可以使用具体化参数并使用它来解析类型。 (注意演员表还是有必要的)
I though setting
<T : Any>
in the method contract would allow to return an implementation of any type.
不,这意味着它具有到return任何类型的实现调用者要求。例如,在 Animesh Sahu 的示例中,resolve<Boolean>("string")
必须 return 和 Interface<Boolean>
,但是您对 resolve
的实现将 return 和 StringImplementation
。当然也可以是resolve<File>("string")
等
allow to return an implementation of any type
被调用的方法选择的恰好是Interface<*>
。