ir2pid
ir2pid

Reputation: 6166

Kotlin Type mismatch, required: x found: x?

I find a lot of arguments have the error

Type mismatch
required: FragmentActivity
found: FragmentActivity?

I'm not sure of what's the best way to address this problem. Currently, I wrap the line in a variable?.let{ statement }

meViewModel = ViewModelProviders.of((iMainActivity as Fragment).activity, vmf).get(MeViewModel::class.java) }

into

val fragmentActivity = (iMainActivity as Fragment).activity

fragmentActivity?.let 
{ 
   meViewModel = ViewModelProviders.of(fragmentActivity, vmf).get(MeViewModel::class.java) 
}

is it the right way to approach this

Upvotes: 6

Views: 14394

Answers (2)

rekire
rekire

Reputation: 47965

Short answer: Yes.

With ?.let you can be sure that the value will be non null, so you have the null safety you would expect. Just keep in mind that in some cases you cannot use the smartcast which you did in your code above.

Smart casts [...] don't work on var properties, and they always work on local variables (val and var). They also don't work on val properties with a custom getter, because val doesn't mean final in Kotlin.

Quote from Marko Topolnik in the comments.

This is because, in a rare edge case, the value could be changed by a different thread. You will get a compile error so that is prevented too. In that case you would need to use the implicit it or define an own alias like here:

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

Upvotes: 1

leonardkraemer
leonardkraemer

Reputation: 6813

Short answer: Yes.

This means that the compiler is not sure if s.th. is !=null. If you are sure that it is not null you can also use:

val fragmentActivity = (iMainActivity as Fragment).activity!!

That gives you FragmentActivity instead of FragmentActivity? and you dont need the ?.let{}

Keep in mind that that might throw a NPE, while the

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

would simply not execute the block within .let{}, which is often less harmful then a NPE. See https://kotlinlang.org/docs/reference/null-safety.html for more.

Upvotes: 5

Related Questions