Using functions with Generics in Kotlin.
fun main() {
val ints = listOf(1, 2, 3, 4, 5)
val shorts: List<Short> = listOf(10, 20, 30, 40, 50)
val floats: List<Float> = listOf(100.3f, -458.43f)
val strings = listOf("1", "2", "3")
val nullableShorts: List<Short?> = listOf(10, 20, 30, 40, 50)
convertToInt2(ints)
println("======")
convertToInt2(shorts)
println("======")
convertToInt2(floats)
println("======")
// convertToInt2(strings) // Nope
append(StringBuilder("String 1"), StringBuilder("String 2")) // StringBuilder conforms to both CharSequence and Appendable
println("======")
convertToInt(nullableShorts) // Will accept because the Generic T has no bounds and is therefore nullable
println("======")
convertToInt3(nullableShorts) // Works as convertToInt3() accepts nullable Numbers
}
fun <T> convertToInt(collection: Collection<T>) {
for (num in collection) {
// println("${num.toInt()}") // Will not accept this as there is no guarantee that what is being passed in is a Number
}
}
// So we restrict the Generic type to a Number class to limit type options:
fun <T: Number> convertToInt2(collection: Collection<T>) {
for (num in collection) {
println("${num.toInt()}") // Works as the compiler knows it is getting a Number
}
}
fun <T> append(item1: T, item2: T)
where T: CharSequence, T: Appendable { // Restricts to both CharSequence and Appendable. Can have multiple interfaces but only one class as an object cannot be e.g. an Int and Short at the same time
println("Append result is ${item1.append(item2)}")
}
// What about nullability? Generic defaults to Any? type so is nullable. But if we specify a bound we need to state nullable if necessary
// So we restrict the Generic type to a Number class to limit type options:
fun <T: Number?> convertToInt3(collection: Collection<T>) { // Use ? to allow null
for (num in collection) {
println("${num?.toInt()}") // Remember to add nullable here too
}
}
// If you want to limit the Collection to only non-nullable types:
fun <T: Any> convertToInt4(collection: Collection<T>) { // Use Any without the ? to specify a non-nullable of any type
for (num in collection) {
println(num)
}
}
