Kotlin Тип несоответствия, требуется: x найдено: x? - PullRequest
0 голосов
/ 23 октября 2018

Я нахожу, что во многих аргументах есть ошибка

Type mismatch
required: FragmentActivity
found: FragmentActivity?

Я не уверен, как лучше всего решить эту проблему.В настоящее время я заключаю строку в переменную? .Let {оператор}

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

в

val fragmentActivity = (iMainActivity as Fragment).activity

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

это правильный подход к этому

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Краткий ответ: Да.

Это означает, что компилятор не уверен, что s.th.это !=null.Если вы уверены, что оно не равно нулю, вы также можете использовать:

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

Это дает вам FragmentActivity вместо FragmentActivity?, и вам не нужно ?.let{}

Keep inИмейте в виду, что это может привести к NPE , в то время как

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

просто не выполнит блок внутри .let{}, который часто менее вреден, чем NPE.Подробнее см. https://kotlinlang.org/docs/reference/null-safety.html.

0 голосов
/ 23 октября 2018

Краткий ответ: Да.

С ?.let вы можете быть уверены, что значение будет ненулевым, поэтому вы ожидаете нулевую безопасность.Просто имейте в виду, что в некоторых случаях вы не можете использовать умную трансляцию, которую вы делали в коде выше.

Умные приведения [...] не работают со свойствами var, и они всегда работают надлокальные переменные (val и var).Они также не работают с val свойствами с пользовательским геттером, потому что val не означает final в котлине.

Цитата из Марко Топольник в комментариях.

Это связано с тем, что в редких случаях значение может быть изменено другим потоком.Вы получите ошибку компиляции, так что это также предотвращается.В этом случае вам нужно будет использовать неявный it или определить собственный псевдоним как здесь:

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