Kotlin 类型不匹配,必需:x 找到:x?

ir2*_*pid 5 android nullable kotlin android-studio

我发现很多论点都有错误

Type mismatch
required: FragmentActivity
found: FragmentActivity?
Run Code Online (Sandbox Code Playgroud)

我不确定解决这个问题的最佳方法是什么。目前,我将该行包装在变量中?.let{statement}

meViewModel = ViewModelProviders.of((iMainActivity as Fragment).activity, vmf).get(MeViewModel::class.java) }
Run Code Online (Sandbox Code Playgroud)

进入

val fragmentActivity = (iMainActivity as Fragment).activity

fragmentActivity?.let 
{ 
   meViewModel = ViewModelProviders.of(fragmentActivity, vmf).get(MeViewModel::class.java) 
}
Run Code Online (Sandbox Code Playgroud)

这是解决这个问题的正确方法吗

leo*_*mer 5

简短回答:是的。

这意味着编译器不确定是否 s.th. 是!=null。如果您确定它不为空,您还可以使用:

val fragmentActivity = (iMainActivity as Fragment).activity!!
Run Code Online (Sandbox Code Playgroud)

这给了你FragmentActivity而不是并且FragmentActivity?你不需要?.let{}

请记住,这可能会引发NPE,而

fragmentActivity?.let { fragment ->
   meViewModel = ViewModelProviders.of(fragment, vmf).get(MeViewModel::class.java) 
}
Run Code Online (Sandbox Code Playgroud)

不会执行 中的块.let{},这通常比 NPE 危害更小。有关更多信息,请参阅https://kotlinlang.org/docs/reference/null-safety.html


rek*_*ire 1

简短回答:是的。

这样?.let您就可以确定该值将不为空,因此您拥有所期望的空安全性。请记住,在某些情况下,您无法使用上面代码中所做的智能广播。

智能转换 [...] 不适用于 var 属性,并且它们始终适用于局部变量(valvar)。它们也不适用于val具有自定义 getter 的属性,因为这val并不意味着final在 Kotlin 中。

评论中引用了Marko Topolnik的话。

这是因为,在极少数情况下,该值可能会被不同的线程更改。你会得到一个编译错误,这样也可以防止这种情况。在这种情况下,您需要使用隐式别名it或定义自己的别名,如下所示:

fragmentActivity?.let { fragment ->
   meViewModel = ViewModelProviders.of(fragment, vmf).get(MeViewModel::class.java) 
}
Run Code Online (Sandbox Code Playgroud)