我想要做的是使用可以是其他三种类型之一的泛型类型。
这是一个有功能的例子:
fun <T> get(key: String) : T where T: String, T: Number, T: Boolean {}
上面的代码不起作用,那我该怎么做呢?
答案 0 :(得分:8)
这不起作用,因为T
无法表示为位于String
,Number
和Boolean
交叉点的某种类型。
如果要将类型限制为预定义类型列表,则密封类是一个很好的解决方案。
sealed class MyData {
class Bool(val data: Boolean) : MyData()
class String(val data: String) : MyData()
class Number(val data: Number) : MyData()
}
fun get(key: String): MyData = TODO()
答案 1 :(得分:1)
在这种情况下,编译器如何知道返回的是什么类型? T
可能是任何东西,所以他们无法定义类似的东西。
您可以定义三种特定于类型的方法:
fun getString(key: String): String = ...
fun getBoolean(key: String): Boolean= ...
fun getInt(key: String): Int = ...
(或者是最常用的包装方法)
答案 2 :(得分:1)
对于KotlinJS,您可以使用ts2kt将TypeScript定义翻译为Kotlin。它确实支持联盟类型,但可能并非所有情况都是完美的。有tests for unionTypes in ts2kt可以解释现在如何处理它们,并且在针对JavaScript平台时,您可以手动创建任何类似的东西。
issue #41 - to add better Union Type support的评论中提到了进一步的工作。最后,该主题至少有一个discussion thread表示:
在JS和TS中,在大多数情况下,联合类型用作重载的替代,因此在不久的将来,我们将尽可能使用重载。 此外,我们考虑提供另外的方法来为本机声明指定联合类型。
还有另一个Stack Overflow问题正在讨论这个问题,并提供了一些当前选项:Kotlin and discriminated unions (sum types),其答案在所有Kotlin目标平台上都有效。
特别是对于JavaScript目标,您可以考虑使用dynamic
type。我至少看到使用此类型的one test case in ts2kt。此示例以此TypeScript代码开头:
declare class Foo
type Key = Key2 | number;
type Key2 = string | Foo;
declare var fooKey: Key;
declare function barKey(a: Key|number);
declare function barList(a: List<Key>);
declare function barArray(a: Key[]);
interface Parent {
(...children: Key[]): Foo;
}
使用dynamic
作为返回类型代替union类型生成此Kotlin;在其他情况下重载方法签名以处理联合类型(我添加的一些评论):
external open class Foo
// using dynamic in place of union type
external var fooKey: dynamic /* String | Foo | Number */ = definedExternally
// using method overloading in place of union type
external fun barKey(a: String): Unit = definedExternally
external fun barKey(a: Foo): Unit = definedExternally
external fun barKey(a: Number): Unit = definedExternally
// using dynamic in place of union type
external fun barList(a: List<dynamic /* String | Foo | Number */>): Unit = definedExternally
external fun barArray(a: Array<dynamic /* String | Foo | Number */>): Unit = definedExternally
external interface Parent {
// using method overloading in place of union type
@nativeInvoke
fun invoke(vararg children: String): Foo
@nativeInvoke
fun invoke(vararg children: Foo): Foo
@nativeInvoke
fun invoke(vararg children: Number): Foo
}
但同样,您应该审核所有ts2kt test cases for union types以查看的其他提示,包括处理undefined
。