我有一种方法可以将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合作,可能不知道可以实现这一目标的语言功能。
答案 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()