Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare a variable with two types in Kotlin, like val x: Int or String

Tags:

types

kotlin

I'm gonna write a method like:

object UIBehavior {
   fun dialog(context: Context, title: Int | String, message: Int | String){
     val dialogObj = AlertDialog.Builder(context)
     dialogObj.setTitle(title)
     dialogObj.setMessage(message)
   }
}

The methods dialogObj.setTitle and dialogObj.setMessage allow two types of parameters, and how can I delare the parameter that can let the method dialog allow only two types Int and String?

like image 676
lam Avatar asked Oct 10 '18 07:10

lam


People also ask

How do I declare a string variable in Kotlin?

To declare a string in Kotlin, we need to use double quotes(” “), single quotes are not allowed to define Strings.

How do you declare Val in Kotlin?

Kotlin uses two different keywords to declare variables: val and var . Use val for a variable whose value never changes. You can't reassign a value to a variable that was declared using val . Use var for a variable whose value can change.

How do you use VAL and VAR in Kotlin?

val and var both are used to declare a variable. var is like general variable and it's known as a mutable variable in kotlin and can be assigned multiple times. val is like Final variable and it's known as immutable in kotlin and can be initialized only single time.

Is int a data type in Kotlin?

There are different data types in Kotlin:Integer Data type. Floating-point Data Type. Boolean Data Type.


2 Answers

You can't do that in Kotlin.

But you can have multiple versions of a function, e.g.

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

That way you can simply call the function with either ids or strings and it looks like you are using the same function

UIBehavior.dialog(this, R.string.title, R.string.message)
UIBehavior.dialog(this, "title", "message")

You could also use a common supertype of Int and String but that would allow a lot more and I wouldn't recommend that.

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

Generics don't work here either because you can't call dialogObj.setTitle(title) dynamically. It must be known at compile time whether you want to call the Int or the String overload of that function. It's also not really different from using Any.

like image 77
zapl Avatar answered Oct 24 '22 20:10

zapl


  1. Generics can be the solution for you.
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. Also using Any can be a solution too:
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)
}
like image 25
Arhan Ashik Avatar answered Oct 24 '22 20:10

Arhan Ashik