泛化参数和返回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()