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

时间:2018-10-10 07:39:58

标签: 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.setTitle dialogObj.setMessage 允许两种类型的参数,而我如何删除可以让方法 dialog 的参数em>只允许Int和String这两种类型吗?

5 个答案:

答案 0 :(得分:2)

您不能在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")

您还可以使用IntString的通用超类型,但这会允许更多的超类,我不建议这样做。

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并没有什么不同。

答案 1 :(得分:0)

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

或者有两种不同的方法。

答案 2 :(得分:0)

您可以使用Any,但是我认为这根本不是一个很好的解决方案。

最好将标题和消息都设置为String或CharSequence以符合setTitle和setMessage类型作为参数。

答案 3 :(得分:0)

谢谢你们,我正在写代码

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()
    }
}

它可以工作,但不确定是否合理

答案 4 :(得分:0)

  1. 泛型可以为您提供解决方案。
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)
}
  1. 也可以使用Any作为解决方案:
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)
}