In my Jetpack compose project, I have a field that can contain different types of serializable data.
val httpBody : Serializable?
get() = when(this) {
is InitiatePayment -> this.pendingTransaction //data class annotated with @Serializable
is VerifyPaymentConfirmation -> this.transactionId //Normal String
is ValidateCart -> this.cartItems //Another data class with @Serializable
else -> null
}
Any? Type works. But when using Serializable?,
Gives the error,
Type mismatch.
Required:
Serializable?
Found:
PendingTransactionDTO
In Swift, I could just do
var httpBody : Codable? {
switch self {
case .initiatePayment(let pendingTransaction):
return pendingTransaction //Codable struct
case .verifyStoreCode(let storeCode):
return storeCode //String
case .verifyPaymentConfirmation(let transactionId):
return transactionId //String
default:
return nil
}
}
In this case, httpBody property accepts everything that implements the Codable interface/protocol.
In short, how to get the property type to accept any class/data class/object that is annotated with @Serializable, plus primitives like String and Int, which I suppose are by default, serializable in Kotlin.
Any tips? Or is it even possible to do this in Kotlin?
CodePudding user response:
Are you using the @Serializable
annotation from the kotlinx.serialization
package? That's just to mark the class for processing by that library - it's unrelated to the Serializable
interface in Java which is the type you're using here. That annotation isn't part of the type system, so you can't use it for this kind of thing.
Depending on how you're actually doing the serialisation, it might be enough for you to add the Serializable
interface type to your class definitions - like the docs for the interface say, it doesn't actually require any methods to be overridden. But if you want to, say, throw it into a Bundle
with putSerializable
, you'll probably have more work to do.
CodePudding user response:
Serializable is an annotation, not a type that a class inherits (unless you're talking about Java's unrelated Serializable interface), so this is not possible. Notably, the various Kotlinx Serialization libraries' encodeTo...
functions have no restriction on the type of the argument. There is no compile-time check to make sure it is Serializable. You might as well make your function return Any?
. The Any?
return type is an acceptable argument for encodeToString
, et. al.