具有可空参数和返回类型的Generalize方法

时间:2017-08-24 12:45:43

标签: kotlin

我有一种方法可以将ByteArray?转换为base64 String?,这样如果参数为null,输出也将是null。这是它的实现:

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

但是当我传入不可空的ByteArray方法时,返回预期的String?。有没有办法使它成为通用的,所以这样的用例是可能的:

val base64 = toBase64String(ByteArray(4))

其中base64的类型为String而不是String?,因为参数不可为空?

我刚开始与Kotlin合作,可能不知道可以实现这一目标的语言功能。

3 个答案:

答案 0 :(得分:5)

你可以做两个重载,一个用于可空ByteArray?,一个用于非空ByteArray

fun toBase64String(array: ByteArray): String =   
    Base64.getEncoder().encodeToString(array)

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

我们需要@JvmName("...")来避免字节码中的声明冲突。  此外,这允许区分Java中的函数。

用法:

val nonNullBytes: ByteArray = TODO()
val nonNullString = toBase64String(nonNullBytes) // the inferred type is String

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

当参数为非null类型ByteArray时,编译器将选择返回非空String的重载。

答案 1 :(得分:2)

对于你的情况,可能重载方法是最好的解决方案,但为了完整起见,这里有另外两种方法来实现只使用一种方法(可空的方法):

Not-Null-Asserted运算符:

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

Evlis运营商:

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

答案 2 :(得分:1)

  

如果参数为null,则输出也将为null

如果这是函数遇到null参数时唯一做的事情,那么最好声明它接受非null值并使用安全调用来处理null:

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)

仅当let不为空时才调用此bytes函数,否则表达式的结果为null。当调用它时,调用lambda函数或指定为其参数的函数引用,将已经检查过的ByteArray传递给该函数。

同样可以更方便地将toBase64String声明为ByteArray的扩展名,因此可以使用安全调用调用它而不使用辅助函数let"

fun ByteArray.toBase64String(): String =   
    Base64.getEncoder().encodeToString(this)

val bytes: ByteArray? = ...
val base64 = bytes?.toBase64String()