Matt Quigley
Matt Quigley

Reputation: 7874

Why does this Kotlin parameter type with an upper bound need a cast?

The following function takes a list of Serializable and a lambda which serializes the individual elements of the list.

    val os = BufferOutputStream()
    fun <T : Serializable> writeList(list: List<Serializable>, emitter: (T, BufferOutputStream) -> Unit) {
        os.writeInt(list.size)
        for (v in list) {        // v is of type Serializable
            emitter(v as T, os)  // why do we need to cast V as T? 
        }
    }

Why would I need to cast v which is of type Serializable to T when T already has to implement Serializable? Doesn't <T : Serializable> establish that a function/lambda that takes Serializable must take T?

Upvotes: 0

Views: 113

Answers (2)

Matt Quigley
Matt Quigley

Reputation: 7874

I wanted to post an example of why it shouldn't compile without a cast.

Imagine there are two classes Class1 and Class2 which implement or extend Serializable. If you call this function with a list that contains Class1 but the emitter takes Class2, then it would be a class cast exception when taking Class1 out of the list and passing it into the emitter which only takes Class2.

In the example that @r2rek posted, the function forces the list and the emitter to be the same classes.

Upvotes: 0

r2rek
r2rek

Reputation: 2243

Yet your emitter doesn't take any Serializable - it takes only T. That is the reason why you need casting - elements of the list are of type Serializable. If you changed it to :

val os = BufferOutputStream()
    fun <T : Serializable> writeList(list: List<T>, emitter: (T, BufferOutputStream) -> Unit) {
        os.writeInt(list.size)
        for (v in list) {
            emitter(v, os)
        }
    }

It wouldn't need casting.

Upvotes: 1

Related Questions