我想编写一个方便的扩展程序,可以在解析Map时同时提取其值。 如果解析失败,该函数应返回默认值。 所有这些都能正常工作,但我想告诉Kotlin编译器,当默认值不为null时,结果也不会为null。 我可以通过Java中的@Contract
注释来实现这一点,但似乎在Kotlin中无法使用。 这可以完成吗? 扩展功能的合同不起作用吗?以下是Kotlin尝试:
import org.jetbrains.annotations.Contract
private const val TAG = "ParseExtensions"
@Contract("_, !null -> !null")
fun Map<String, String>.optLong(key: String, default: Long?): Long? {
val value = get(key)
value ?: return default
return try {
java.lang.Long.valueOf(value)
} catch (e: NumberFormatException) {
Log.e(TAG, e)
Log.d(TAG, "Couldn't convert $value to long for key $key")
default
}
}
fun test() {
val a = HashMap<String, String>()
val something: Long = a.optLong("somekey", 1)
}
在上面的代码中,即使使用非空默认值1调用optLong,IDE也会在分配给something时突出显示错误。为了比较,在Java中测试可为空性的类似代码如下所示,该代码使用注释和合同:
public class StackoverflowQuestion
{
@Contract("_, !null -> !null")
static @Nullable Long getLong(@NonNull String key, @Nullable Long def)
{
// Just for testing, no real code here.
return 0L;
}
static void testNull(@NonNull Long value) {
}
static void test()
{
final Long something = getLong("somekey", 1L);
testNull(something);
}
}
上面的代码没有显示任何错误。只有当删除
@Contract
注释时,IDE才会警告使用可能为null值调用testNull()
。
string.toLongOrNull()
代替Long.valueOf(string)
,它可以自动处理错误格式。 - killjoydefault
参数默认设置为null
。 - Aro