https://kotlinlang.org logo
#announcements
Title
# announcements
f

Florian

08/06/2021, 10:34 AM
When is it appropriate to use the
!!
operator? Example: In an edit and delete situation I never expect the
todoId
to be null, only when a new todo was added. Does it make sense to just use
!!
then instead of the null-safe operator?
Copy code
fun onAddEditResult(result: Int, todoId: Long? = null) {
        viewModelScope.launch {
            when (result) {
                RESULT_TODO_ADDED -> eventChannel.send(Event.ShowTodoSavedConfirmationMessage("Todo added"))
                RESULT_TODO_EDITED -> {
                    eventChannel.send(Event.ShowTodoSavedConfirmationMessage("Todo updated"))
                    setExpandedState(todoId!!, false)
                }
                RESULT_TODO_DELETED -> {
                    val todo = todoDao.getTodoById(todoId!!)
                    todo?.let {
                        todoDao.delete(todo)
                        setExpandedState(todo.id, false)
                        eventChannel.send(Event.ShowUndoDeleteTodoMessage(todo))
                    }
                }
            }
        }
    }
e

ephemient

08/06/2021, 10:41 AM
seems like this would be better modeled as a
Copy code
sealed class Todo {
    object Added : Todo()
    data class Edited(val todoId: Long) : Todo()
    data class Deleted(val todoId: Long) : Todo()
}
then you can't have such inconsistency between input arguments
👍 1
f

Florian

08/06/2021, 10:52 AM
but I'm getting the result as an Int flag because it's sent over screens
y

Youssef Shoaib [MOD]

08/06/2021, 3:07 PM
You can use a custom Parcelable implementation then to store those classes as different values
f

Florian

08/06/2021, 3:15 PM
as far as I know, Parcelable is not supported by default in Compose and I don't want to hack something together
y

Youssef Shoaib [MOD]

08/06/2021, 3:18 PM
Ohhhh it's compose. Can you only send Ints through? Because if you can send Strings, you could use kotlinx-serialization to serialize those classes
f

Florian

08/06/2021, 3:24 PM
sorry I forgot that this is not the Compose channel
yea I can send a string but is my approach really so bad?
Wait, a sealed class might work. Let me try it out.
y

Youssef Shoaib [MOD]

08/06/2021, 3:31 PM
I would say it isn't bad per se like using
!!
here is absolutely acceptable. What the people here and I are getting at though is that isn't expandable easily and it requires the developer working on the code to know that this long can only be those 3 values and that if it is those 2 values then the other long cannot be null etc. Simply, it just seems like it isn't documented based on the types. If this is jsut a personal hobby project, then sure this works. But if it was for something more professional or if you want to do it "The Right Way" then using a sealed class is best
f

Florian

08/06/2021, 3:36 PM
@Youssef Shoaib [MOD] Thanks for the explanation. It totally makes sense to me now!
The problem is I'm sending this result between screens, through the SavedStateHandle in Compose, which only supports primitive types. I could send it by wrapping it into LiveData but that feels hacky. I think we are meant to send primitive types between screens only.
serializing it into a string also feels weird
y

Youssef Shoaib [MOD]

08/06/2021, 3:44 PM
If it is through Saved State, then AFAIK it saves it into a bundle, which supports Parcelable. Lemme check really quickly though
f

Florian

08/06/2021, 3:46 PM
@Youssef Shoaib [MOD] yea I think that works 👍
I think Compose doesn't accept Parcelables for navigation arguments but the SavedStateHandle does
y

Youssef Shoaib [MOD]

08/06/2021, 3:50 PM
Yeahhh and worst case scenario you can pass the serialized object as JSON
f

Florian

08/06/2021, 3:59 PM
I implemented it as a sealed class now and I like it 👍
thanks again
e

eygraber

08/06/2021, 5:01 PM
To answer your original question,
!!
is appropriate wherever you decide it is. For example, on my team I've decided that it's almost never appropriate because it's usually indicative that something was designed wrong. It's allowed if it's deep in a 3rd party integration, and even then only if there's no feasible way to refactor.
f

Florian

08/06/2021, 5:13 PM
alright, thank you @eygraber
c

Colton Idle

08/06/2021, 9:47 PM
@Florian I asked this question a while back and got some good responses from Roman Elizarov and Adam Powell. The two best things I took out of that question was 1. It's okay to use !! when you basically mean that "if this is null, then something in the universe is wrong" Basically you're okay if the app crashes because it is truly unexpected 2. I think adam powell basically equated it to squeezing a tube of toothpaste. You can work with nullable data types but you hopefully squeeze them into being something more concrete as data flows through different layers of your app. Overall, I was basically able to take the stance that "!! is not evil like some people make it out to be" I'll try to search for the convo
Found both! Really good reads. You can see that some people come out strongly against it, but it was nice to see someone like Roman say that it's a perfectly fine way to require not null https://kotlinlang.slack.com/archives/C0922A726/p1570446700141800 https://kotlinlang.slack.com/archives/C0B8M7BUY/p1601007223034000
f

Florian

08/06/2021, 9:54 PM
@Colton Idle Thank you. Yea I also thought the same way. If the value should really never be null then crashing is probably better than ignoring it.
👍 1
c

Colton Idle

08/06/2021, 10:05 PM
Jake Wharton also has some very very good tweets on this topic if you feel like using twitter advanced search.
He taught me what an invariant was. 😄
e

eygraber

08/06/2021, 10:11 PM
Using it as an assert can lead to some difficulty with debugging in certain scenarios (I tend to use it on scripts out throwaway projects a lot despite not allowing it in my main project).
requireNotNull
helps a lot with debugging, although it can't be used the same way as
!!
e

ephemient

08/07/2021, 12:24 AM
checkNotNull()
and
requireNotNull()
both return the non-null value, so they can be used like
!!
, but allow you to attach a message as well
they also work with smart-casting like
!!
does, so I'm not sure what you mean by "it can't be use in the same way as `!!`"?
e

eygraber

08/08/2021, 1:50 AM
Sorry, I could've been clearer with that. I meant that it's a bit more awkward to use inline than
!!
e

ephemient

08/08/2021, 3:04 AM
if you need it in postfix position,
.let { checkNotNull(it) }
could work, but it is pretty long and awkward. can't compare to the succinctness of
!!
, that's for sure
8 Views