如何将操作应用于 class 中的泛型类型这是使用泛型
How to apply actions to generic types in class this is working with generics
我现在正试图弄清楚泛型是如何工作的。我找到了这个例子
class SomeGenericClass <T> {
fun <T> makeSomething(someData : T) : T {
var localData = someData
//... doing some actions
return localData
}
}
我现在想知道 - 我们如何将一些操作应用于作为参数传递到 makeSomething 方法的泛型类型。有可能吗?我们能否对 someData 应用一些操作或更改(不是可以使用 Any 对象 -toString、hashCode 完成的基本操作)。我认为这是不可能的,对吗?
或者这个例子:
fun <T> doJob(valOne: T, valTwo: T){
}
我们不能对 valOne 和 valTwo 对象应用任何操作。在这两种情况下,我们都需要扩展基本的 class 或接口并覆盖这些方法?
如果您限制 T
类型可以是什么,则可以在具有泛型类型参数的实例上使用方法,例如:
fun <T : CharSequence> useThing(thing: T) {
println(thing)
}
另一种处理传入对象的方法是提供对其进行操作的 lambda,它接收相同的泛型。在调用站点,这将使其参数作为实际类型可用:
fun <T> performActions(thing: T, actions: (T) -> Unit) {
actions(thing)
}
performActions(25) { thing: Int ->
println(3 * thing)
}
第二个示例并不是很明智,但是例如您可以在第二个示例中多次执行该操作。
问题是:你想用它们做什么?
正如所写,您对 T
的唯一了解是它是某种类型 — 因为您不知道 哪个 类型,所以您无能为力类型特定的。因此,您可以对 T
类型的值做的唯一事情是对 所有 类型有效的事情——即您可以用 Any?
做的事情。这包括比较它们与其他类型(或 null
)的相等性(或同一性),将它们转换为 String
s,将它们存储在集合中,以及类似的。
要进行更多操作,您需要进一步了解 T
是什么类型。例如,如果您知道它是一个 CharSequence
(例如 String
),那么您可以通过提供类型绑定来告诉编译器,例如<T : CharSequence>
.
然后您可以用 T
做任何您可以用 CharSequence
做的事情,例如获取它的长度、遍历或映射它的字符,&c。 (根据 )。但是,编译器会阻止您使用不相关的 class.
调用它
因此,对于泛型 — 与任何其他代码一样 — 您可以对对象执行的操作取决于您对其类型的了解。
(顺便说一句,您引用的代码有点误导,因为它有两个不同类型的参数,称为 T
:一个在 class 级别,另一个在函数中。如果在这两种情况下你的意思是相同的 T
,那么你可能想从函数定义中删除 <T>
。)
我现在正试图弄清楚泛型是如何工作的。我找到了这个例子
class SomeGenericClass <T> {
fun <T> makeSomething(someData : T) : T {
var localData = someData
//... doing some actions
return localData
}
}
我现在想知道 - 我们如何将一些操作应用于作为参数传递到 makeSomething 方法的泛型类型。有可能吗?我们能否对 someData 应用一些操作或更改(不是可以使用 Any 对象 -toString、hashCode 完成的基本操作)。我认为这是不可能的,对吗? 或者这个例子:
fun <T> doJob(valOne: T, valTwo: T){
}
我们不能对 valOne 和 valTwo 对象应用任何操作。在这两种情况下,我们都需要扩展基本的 class 或接口并覆盖这些方法?
如果您限制 T
类型可以是什么,则可以在具有泛型类型参数的实例上使用方法,例如:
fun <T : CharSequence> useThing(thing: T) {
println(thing)
}
另一种处理传入对象的方法是提供对其进行操作的 lambda,它接收相同的泛型。在调用站点,这将使其参数作为实际类型可用:
fun <T> performActions(thing: T, actions: (T) -> Unit) {
actions(thing)
}
performActions(25) { thing: Int ->
println(3 * thing)
}
第二个示例并不是很明智,但是例如您可以在第二个示例中多次执行该操作。
问题是:你想用它们做什么?
正如所写,您对 T
的唯一了解是它是某种类型 — 因为您不知道 哪个 类型,所以您无能为力类型特定的。因此,您可以对 T
类型的值做的唯一事情是对 所有 类型有效的事情——即您可以用 Any?
做的事情。这包括比较它们与其他类型(或 null
)的相等性(或同一性),将它们转换为 String
s,将它们存储在集合中,以及类似的。
要进行更多操作,您需要进一步了解 T
是什么类型。例如,如果您知道它是一个 CharSequence
(例如 String
),那么您可以通过提供类型绑定来告诉编译器,例如<T : CharSequence>
.
然后您可以用 T
做任何您可以用 CharSequence
做的事情,例如获取它的长度、遍历或映射它的字符,&c。 (根据
因此,对于泛型 — 与任何其他代码一样 — 您可以对对象执行的操作取决于您对其类型的了解。
(顺便说一句,您引用的代码有点误导,因为它有两个不同类型的参数,称为 T
:一个在 class 级别,另一个在函数中。如果在这两种情况下你的意思是相同的 T
,那么你可能想从函数定义中删除 <T>
。)