Generalizar método con arguments anulables y tipo de retorno

Tengo un método que convierte ByteArray? a base64 String? de modo que si el argumento fue null salida también será null . Esta es su implementación:

 fun toBase64String(array: ByteArray?): String? = if(array == null) null else Base64.getEncoder().encodeToString(array) 

Pero cuando paso el método no anulable ByteArray devuelve String? que se espera ¿Hay alguna manera de hacerlo genérico por lo que dicho caso de uso será posible:

 val base64 = toBase64String(ByteArray(4)) 

donde base64 será de tipo String y no String? ya que el argumento no fue nulo?

Empecé a trabajar con Kotlin y probablemente no conozco la function de idioma que pueda hacer esto posible.

Puedes hacer dos sobrecargas, una para ByteArray? nulos ByteArray? y uno para ByteArray no nulo:

 fun toBase64String(array: ByteArray): String = Base64.getEncoder().encodeToString(array) @JvmName("toBase64StringNullable") fun toBase64String(array: ByteArray?): String? = if (array == null) null else toBase64String(array) 

Necesitamos @JvmName("...") para evitar el conflicto de statement en el bytecode. Además, esto permite distinguir las funciones en Java.

Uso:

 val nonNullBytes: ByteArray = TODO() val nonNullString = toBase64String(nonNullBytes) // the infernetworking type is String val nullableBytes: ByteArray? = TODO() val nullableString = toBase64String(nullableBytes) // the infernetworking type is String? 

Cuando el argumento es del tipo no nulo ByteArray , el comstackdor elegirá la sobrecarga que devuelve una String no nula.

Probablemente los methods de sobrecarga sean la mejor solución para su caso, pero para completar, hay otras dos forms de darse count de que usando solo un método (el que se puede anular):

Operador no anulado por el cero:

 val base64: String = toBase64String(ByteArray(4))!! 

Operador de Evlis:

 val base64: String = toBase64String(ByteArray(4)) ?: "defaultString" 

si el argumento fue nulo, la salida será nula también

Si eso es lo único que hace la function cuando encuentra un argumento nulo, es mejor declarar que acepta valores no nulos y usar la llamada segura para tratar con nulos:

 fun toBase64String(array: ByteArray): String = Base64.getEncoder().encodeToString(array) val bytes: ByteArray? = ... val base64 = bytes?.let { toBase64String(it) } // the same can be written with function reference instead of lambda val base64 = bytes?.let(::toBase64String) 

Aquí, let function se llama solo cuando bytes no es nulo; de lo contrario, el resultado de la expresión es null . Cuando se invoca invoca la function lambda o la reference de function especificada como su argumento, pasando ByteArray que ya se ha comprobado que no es nulo para esa function.

También puede ser más conveniente declarar toBase64String como una extensión para ByteArray , por lo que se puede invocar con una llamada segura sin la function de ayuda ".

 fun ByteArray.toBase64String(): String = Base64.getEncoder().encodeToString(this) val bytes: ByteArray? = ... val base64 = bytes?.toBase64String() 
  • Kotlin: isAssignableFrom y reflexiones del tipo de reflexión
  • Error de Android Kotlin: "tipo de devolución es 'unidad' que no es un subtipo de reemplazado"
  • C ++ Enum equivalente en Kotlin
  • Validar files XML grandes contra grandes XSD, ¿hay alguna manera rápida de hacerlo?
  • ¿Cómo consultar el tipo de datos de reference Firebase Firestre?
  • Iconos de IntelliJ y Android Studio para files de Kotlin
  • Android Espresso IntentsMatcher funciona en un dispositivo nuevo pero no antiguo
  • ¿Puedo inferir el tipo de una propiedad en el delegado?
  • No se permite declarar una tarea 'limpia' personalizada cuando se usan los complementos estándar de ciclo de vida de Gradle
  • Spring ConfigurationProperties y Kotlin?
  • setSmallIcon (icon: Icon) y NotificationCompat