最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kotlin - Disambiguate name conflict and reference class parameter - Stack Overflow

programmeradmin3浏览0评论

In Kotlin, class parameter names are visible to the user of the class. I want to define onClick as a parameter, but the class already has a function named onClick, and I cannot reference the parameter.

How do I reference a class parameter whose name conflicts with a method name?

So far the best thing I could do was copying the parameter to a field. I am not sure if it is worth doing: it moves the ugliness inside a class, but that class is in the same project, to be maintained by the same people.

open class A() { // Already exists, I cannot change it
    open fun onClick() {
        println("A.onClick()")
    }
}

class B(onClick: () -> Unit = { println("param onClick()") }) : A() {
    var x = 2
    private val uglyOnClick = onClick // workaround: one more field for the same value (ugh!)
    override fun onClick() {
        println("B.onClick() $x")
        if (x-- > 0) { // prevent endless recursion in case recursion happens (ideally, it should not)
            super.onClick()
            //[email protected]() // recursion, but I need to reference the class parameter
            //this.onClick() // recursion, but I need to reference the class parameter
            //onClick() // recursion, but I need to reference the class parameter
            /* any of the above three print:
                B.onClick() 2
                A.onClick()
                B.onClick() 1
                A.onClick()
                B.onClick() 0
             */
            //getOnClick() // Unresolved reference: getOnClick
            uglyOnClick() // this one works as expected, but it's an ugly workaround
            /* the one above prints, as expected:
                B.onClick() 2
                A.onClick()
                param onClick()
             */
        }
    }
}

What is required:

class B(onClick: () -> Unit = { println("param onClick()") }) : A() {
    override fun onClick() {
            println("B.onClick()")
            super.onClick()
            :::MAGIC:::.onClick()
        }
    }
}
/* it must print:
    B.onClick()
    A.onClick()
    param onClick()
*/

In Kotlin, class parameter names are visible to the user of the class. I want to define onClick as a parameter, but the class already has a function named onClick, and I cannot reference the parameter.

How do I reference a class parameter whose name conflicts with a method name?

So far the best thing I could do was copying the parameter to a field. I am not sure if it is worth doing: it moves the ugliness inside a class, but that class is in the same project, to be maintained by the same people.

open class A() { // Already exists, I cannot change it
    open fun onClick() {
        println("A.onClick()")
    }
}

class B(onClick: () -> Unit = { println("param onClick()") }) : A() {
    var x = 2
    private val uglyOnClick = onClick // workaround: one more field for the same value (ugh!)
    override fun onClick() {
        println("B.onClick() $x")
        if (x-- > 0) { // prevent endless recursion in case recursion happens (ideally, it should not)
            super.onClick()
            //[email protected]() // recursion, but I need to reference the class parameter
            //this.onClick() // recursion, but I need to reference the class parameter
            //onClick() // recursion, but I need to reference the class parameter
            /* any of the above three print:
                B.onClick() 2
                A.onClick()
                B.onClick() 1
                A.onClick()
                B.onClick() 0
             */
            //getOnClick() // Unresolved reference: getOnClick
            uglyOnClick() // this one works as expected, but it's an ugly workaround
            /* the one above prints, as expected:
                B.onClick() 2
                A.onClick()
                param onClick()
             */
        }
    }
}

What is required:

class B(onClick: () -> Unit = { println("param onClick()") }) : A() {
    override fun onClick() {
            println("B.onClick()")
            super.onClick()
            :::MAGIC:::.onClick()
        }
    }
}
/* it must print:
    B.onClick()
    A.onClick()
    param onClick()
*/
Share Improve this question edited Apr 1 at 7:55 jonrsharpe 122k30 gold badges268 silver badges475 bronze badges asked Apr 1 at 7:44 1844674407370955161518446744073709551615 16.9k4 gold badges101 silver badges132 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 3

The onClick parameter you're passing to B is a constructor parameter, and you can only access it inside B's constructor code and property initializers. It won't be available later, which is why you can't access it inside the onClick() function.

To fix it:

  1. Add the val keyword to the constructor parameter, turning it into a property that will be stored with the object.
  2. Use invoke() to make sure you're referencing the property, not the function.
class B(val onClick: () -> Unit = { println("param onClick()") }) : A() {
  override fun onClick() {
    onClick.invoke()
  }
}
发布评论

评论列表(0)

  1. 暂无评论