我现在试图弄清楚泛型是如何工作的。我找到了这个例子
guard let data = snapshot.value as? [String :[String:String]] else { return }
data.values.forEach {
print($0["Latitude"])
print($0["Longitude"])
}
我现在想知道-我们如何对作为参数传递给 makeSomething 方法的泛型类型应用某些操作。有可能吗?我们是否可以对someData应用某些操作或更改(不是可以通过Any对象-toString,hashCode完成的基本操作)。我不可能这样做,对吗? 或以下示例:
class SomeGenericClass <T> {
fun <T> makeSomething(someData : T) : T {
var localData = someData
//... doing some actions
return localData
}
}
我们无法对valOne和valTwo对象应用任何操作。在这两种情况下,我们都需要扩展基本类或接口并覆盖这些方法?
答案 0 :(得分:3)
如果您限制T
类型的类型,则可以在具有泛型类型参数的实例上使用方法,例如:
fun <T : CharSequence> useThing(thing: T) {
println(thing)
}
处理传入的对象的另一种方法是提供对其进行操作的lambda,该lambda接收相同的泛型类型。在呼叫站点,这将使其参数可用作实际类型:
fun <T> performActions(thing: T, actions: (T) -> Unit) {
actions(thing)
}
performActions(25) { thing: Int ->
println(3 * thing)
}
第二个示例虽然不是很明智,但是例如,您可以在第二个示例中多次执行操作。
答案 1 :(得分:1)
问题是:您想与他们做什么?
按照书面规定,您对T
唯一了解的是某种类型-因为您不知道哪种类型,因此您无法执行任何特定于类型的操作。因此,对于类型为T
的值,您唯一可以做的事情就是对所有 all 类型都有效的东西,即可以对Any?
进行的事情。这包括将它们的相等性(或同一性)与其他类型(或null
)进行比较,将它们转换为String
,将它们存储在集合中,等等。
要执行更多操作,您需要进一步了解T
是什么类型。例如,如果您知道它是CharSequence
(例如String
),则可以通过指定类型绑定来告诉编译器,例如<T : CharSequence>
。
然后,您可以使用T
进行与CharSequence
相同的任何操作,例如获取其长度,遍历或映射其字符,&c。 (根据zsmb13's answer)。但是,编译器将阻止您使用不相关的类对其进行调用。
因此,与泛型一样(与任何其他代码一样),对对象可以执行的操作取决于对对象类型的了解。
(顺便说一句,引用的代码有点误导,因为它有两个不同的类型参数,称为T
:一个在类级别,另一个在函数中。如果您的意思是相同的{{ 1}},那么您可能要从函数定义中删除T
。)