如何在类中将操作应用于类中的泛型类型

时间:2019-03-01 14:38:32

标签: generics kotlin generic-programming

我现在试图弄清楚泛型是如何工作的。我找到了这个例子

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对象应用任何操作。在这两种情况下,我们都需要扩展基本类或接口并覆盖这些方法?

2 个答案:

答案 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。)