Luke Needham
Luke Needham

Reputation: 3989

Why can't I use `MutableState` as a property delegate?

I am trying to use an instance of MutableState as a property delegate.

Here's what I have:

val countState = remember { mutableStateOf(0) }

Here's what I want:

var count by remember { mutableStateOf(0) }

However, when I use the by keyword, I get the compiler error:

Type 'TypeVariable(T)' has no method 'getValue(Nothing?, KProperty<*>)' and thus it cannot serve as a delegate

What's going wrong?

Upvotes: 20

Views: 6774

Answers (1)

Luke Needham
Luke Needham

Reputation: 3989

To serve as a delegate, MutableState needs a getValue function (for reading values), and a setValue function (for writing values).

When you access MutableState via mutableStateOf, you use the import:

import androidx.compose.runtime.mutableStateOf

However, this import does not include the getValue and setValue functions for MutableState - they are defined as extension functions in a separate file. To access them, an explicit import on that file is required.

This by itself is not usually a problem - if you type:

countState.getValue(...)

Android Studio will auto-suggest the required import for you.

It is a problem, however, when you use the by keyword - Android Studio will not auto-suggest the import for you. Instead, it will give the cannot serve as a delegate error, without any indication of what you need to do.

So the fix is to manually add the imports for the extension functions yourself:

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

Hopefully someone on the IDE team can make this more obvious in the future - an auto-suggestion for the import would be ideal!

Upvotes: 59

Related Questions