Types 如何在Kotlin中声明具有两种类型的变量,如val x:Int或String

Types 如何在Kotlin中声明具有两种类型的变量,如val x:Int或String,types,kotlin,Types,Kotlin,我要写一个方法,比如: object UIBehavior { fun dialog(context: Context, title: Int | String, message: Int | String){ val dialogObj = AlertDialog.Builder(context) dialogObj.setTitle(title) dialogObj.setMessage(message) } } dialogObj.setTitl

我要写一个方法,比如:

object UIBehavior {
   fun dialog(context: Context, title: Int | String, message: Int | String){
     val dialogObj = AlertDialog.Builder(context)
     dialogObj.setTitle(title)
     dialogObj.setMessage(message)
   }
}
dialogObj.setTitle和dialogObj.setMessage方法允许两种类型的参数,我如何才能删除允许方法对话框仅允许两种类型Int和String的参数?

您可以使用相同的方法,并检查方法体中的类型


或者有两种不同的方法。

在Kotlin中不能这样做

但是一个函数可以有多个版本,例如

object UIBehavior {
    fun dialog(context: Context, titleId: Int, messageId: Int){
        val titleString = context.getString(titleId)
        val messageString = context.getString(messageId)
        dialog(context, titleString, messageString)
    }

    fun dialog(context: Context, title: String, message: String) {
        val dialogObj = AlertDialog.Builder(context)
        dialogObj.setTitle(title)
        dialogObj.setMessage(message)
    }
}
这样,您可以简单地使用id或字符串调用函数,看起来您使用的是同一个函数

UIBehavior.dialog(this, R.string.title, R.string.message)
UIBehavior.dialog(this, "title", "message")
您还可以使用一个常见的超类型
Int
String
,但这将允许更多,我不建议这样做

fun dialog(context: Context, title: Any, messageId: Any){
    val titleString = when (title) {
        is String -> title
        is Int -> context.getString(title)
        else -> throw IllegalArgumentException("Unsupported type")
    }
    val messageString = when ...
       ...
    dialog(context, titleString, messageString)
}

泛型在这里也不起作用,因为您不能动态调用
dialogObj.setTitle(title)
。必须在编译时知道是要调用该函数的
Int
还是
String
重载。它与使用
Any
也没有什么不同,您可以使用Any,但我认为这根本不是一个很好的解决方案


最好将标题和消息都设置为字符串或字符序列,与setTitle和setMessage作为参数的类型一致。

谢谢大家,我正在编写代码

interface DialogOption {
    val title: Any
    val message: Any
    val positiveBtnTxt: Any
    val negativeBtnTxt: Any
    fun confirm(d: DialogInterface, n: Int) {
        d.dismiss()
    }
    fun cancel(d: DialogInterface, n: Int) {
        d.dismiss()
    }

}

object UIBehavior {
    fun dialog(context: Context, opt: DialogOption) {
        val dialogObj = AlertDialog.Builder(context)
        val title = opt.title
        val message = opt.message
        val poTxt = opt.positiveBtnTxt
        val negTxt = opt.negativeBtnTxt
        fun positiveCallback(d: DialogInterface, n: Int) {
            opt.confirm(d, n)
        }

        fun negativeCallback(d: DialogInterface, n: Int) {
            opt.cancel(d, n)
        }

        if (title is String) {
            dialogObj.setTitle(title)
        } else if (title is Int) {
            dialogObj.setTitle(title)
        }
        if (message is String) {
            dialogObj.setMessage(message)
        } else if (message is Int) {
            dialogObj.setMessage(message)
        }
        if (poTxt is String) {
            dialogObj.setPositiveButton(poTxt, ::positiveCallback)
        } else if (poTxt is Int) {
            dialogObj.setPositiveButton(poTxt, ::positiveCallback)
        }
        if ( negTxt is String) {
            dialogObj.setNegativeButton(negTxt, ::negativeCallback)
        } else if (negTxt is Int) {
            dialogObj.setNegativeButton(negTxt, ::negativeCallback)
        }

        dialogObj.show()
    }
}
它有效,但不确定是否合理

  • 泛型可以为您提供解决方案

  • 我不确定这是否可能。如果您熟悉Scala,那么编写两个有趣的签名来调用另一个有趣的对话框可能会更容易,而Kotlin
    setTitle(Int)
    setTitile(String)
    实际上是两个不同的方法,它们恰好共享相同的名称。您的建议是不明确的,因为它必须根据您使用的方法调用不同的方法。
    fun <T>dialog(context: Context, title: T, message: T){
       if(title !is String || title !is Int) throw InvalidParameterException()
       val dialogObj = AlertDialog.Builder(context)
       dialogObj.setTitle(title)
       dialogObj.setMessage(message)
    }
    
    fun dialog(context: Context, title: Any, message: Any){
       if(title !is String || title !is Int) throw InvalidParameterException()
       val dialogObj = AlertDialog.Builder(context)
       dialogObj.setTitle(title)
       dialogObj.setMessage(message)
    }