泛化参数和返回types的泛化方法

我有一个方法来转换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将是types的String而不是String? 因为争论是不可空的?

我刚刚开始与Kotlin合作,可能不知道可以使这成为可能的语言function。

你可以做两个重载,一个是可空的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中的function。

用法:

 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? 

当参数为非空typesByteArray ,编译器将选择返回非空String的重载。

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

Not-Null-Asserted运算符:

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

Evlis经营者:

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

如果参数为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不为空时被调用,否则expression式的结果为null 。 调用时调用lambda函数或指定的函数引用作为其参数,将已经检查为非空的ByteArray传递给该函数。

另外将toBase64String声明为ByteArray的扩展可以更方便,因此可以在没有帮助函数的情况下使用安全调用来调用“

 fun ByteArray.toBase64String(): String = Base64.getEncoder().encodeToString(this) val bytes: ByteArray? = ... val base64 = bytes?.toBase64String()