How to deal with generic bounds migrating from Java to Kotlin?

前端 未结 1 458
名媛妹妹
名媛妹妹 2021-01-22 03:57

My goal is to have the interface methods accept the class type of the implementation. Here\'s the code I have written so far:

internal interface Diff         


        
1条回答
  •  忘掉有多难
    2021-01-22 04:20

    The reason why this "worked" in Java was because uses the raw type Diff. Don't do this!


    The closest you can get is to use a recursive type bound:

    interface Diff> {
        fun lessThan(other: T): Boolean
    }
    

    The problem is, you can substitute any other subtype of Diff.

    However, when using the Diff, use the generic type constraint T : Diff:

    fun > diffUser(diff1: T, diff2: T) {
        println(diff1.lessThan(diff2))
    }
    

    and any Diff that doesn't implement Diff will not be accepted.

    Example:

    class CDiff(private val value: Int) : Diff { // <-- Wrong type!
        override fun lessThan(other: DDiff) = value < other.value
    }
    
    class DDiff(val value: Int) : Diff {
        override fun lessThan(other: DDiff) = value < other.value
    }
    
    fun test() {
        diffUser(CDiff(3), CDiff(4)) // <-- Doesn't compile due to the generic constraint
        diffUser(DDiff(3), DDiff(4))
    }
    

    This same approach is used by the Comparable class.


    Although this works, what you really want is a "self type" and this is not supported, although it was on the roadmap at some point. I believe JetBrains denied the request for this, though I cannot find the bug report.

    This answer details a workaround in Java using the CRT pattern, though it is not necessarily type safe.

    0 讨论(0)
提交回复
热议问题