在 sharedPref.getString 中有一个默认值有什么意义?

sza*_*ske 13 android sharedpreferences kotlin

我正在SharedPreferences通过以下方式访问我的 Android 应用程序

private val sharedPref = PreferenceManager.getDefaultSharedPreferences(context)`
Run Code Online (Sandbox Code Playgroud)

然后尝试使用它从中获取数据

val lat: String = sharedPref.getString("MyKey", "Default")
Run Code Online (Sandbox Code Playgroud)

但是这一行给了我一个错误读数 "Type mismatch. Required String, found String?"

根据文档,getString 方法中的第二个参数表示“如果此首选项不存在,则返回此值可能为空。

那么如果该值可以为空,那么拥有默认值有什么意义呢?我似乎无法获得永远使用的默认值,我可以让我的代码工作的唯一方法是使用 elvis 运算符并将我的代码重写为:

val lat: String = sharedPref.getString("MyKey", "Default") ?: "Default"
Run Code Online (Sandbox Code Playgroud)

哪个看起来很丑。我疯了吗?我错过了什么?

Dem*_*god 15

以这样的方式考虑这一点: 中的每个String偏好都SharedPreferences可以存在存在,可以是null不存在。所以代码

val lat: String = sharedPref.getString("MyKey", "Default") ?: "Not Set"
Run Code Online (Sandbox Code Playgroud)

将返回:

  • Default 如果此 Key 的首选项不存在(意味着此 Key 没有映射)
  • Not Set如果首选项存在,但是是null(将 Key 映射到nullcreated)
  • 任何其他,value如果首选项存在并且映射的值不是null

更新

显然,SharedPreferences 没有我想象的那么聪明。在内部拥有此代码:

String v = (String)mMap.get(key);
return v != null ? v : defValue;
Run Code Online (Sandbox Code Playgroud)

null 只有当我们null作为默认值传递时它才会返回(并且没有保存任何值)。这意味着我们实际上不需要 elvis 选项,我们也不会获得"Not Set"价值。此方法返回可空值,只是因为它允许您将可空值作为默认值传递。


ישו*_*ותך 5

这是因为在阅读以下代码时会启动 kotlin Null-Safety:

val lat: String = sharedPref.getString("MyKey", "Default")
Run Code Online (Sandbox Code Playgroud)

如果您访问SharedPreferences代码,您可以看到以下代码

@Nullable
String getString(String key, @Nullable String defValue);
Run Code Online (Sandbox Code Playgroud)

这给了我们使用 null 作为defValue参数的概率。所以,Kotlin 尝试保护它并给你匹配错误:

“类型不匹配。需要字符串,找到字符串?”

您可以通过为您的 String 变量启用 nullable 来解决问题:

val lat: String? = sharedPref.getString("MyKey", "Default")
Run Code Online (Sandbox Code Playgroud)

虽然这是针对Kotlin 类型系统的目的

Kotlin 的类型系统旨在消除代码中空引用的危险,也称为“十亿美元错误”。