Каковы преимущества @Immutable в классе данных?

Глядя на документацию Immutable, есть пример кода:

@Immutable
data class Person(val name: String, val phoneNumber: String)

@Composable
fun PersonView(person: Person) {
    Column {
        Row {
            Text("Name: ")
            Text(person.name)
        }
        Row {
            Text("Phone: ")
            Text(person.phoneNumber)
        }
    }
}

@Composable
fun PeopleView(people: List<Person>) {
    Column {
        for (person in people) {
            PersonView(person)
        }
    }
}

и подпись:

Пометка Person immutable позволяет пропускать вызовы Composable функции PersonView, если это тот же человек, что и во время последней композиции.

Мой вопрос:

Если рекомпозиция происходит только тогда, когда изменяются аргументы функции @Composable, а классы данных, такие как Person в приведенном выше коде (т.е. содержащие только примитивные vals), не могут быть изменены без создания нового экземпляра, то в чем тут оптимизация?
Когда вызовы функции PersonView Composable будут пропущены по сравнению с тем же кодом, но без аннотации @Immutable? Это как-то связано с изменяемым/нестабильным аргументом people: List<Person> из PeopleView?

9
0
273
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если класс Person объявлен в том же модуле, нет никакой разницы (с @Immutable или без него), потому что компилятор Compose автоматически сделает вывод, что Composable можно пропустить. Вы можете проверить это, сгенерировав отчеты компилятора Compose.

Однако, когда Person поступает из другого модуля в многомодульном приложении (или из внешней библиотеки) и не имеет аннотации @Immutable, то Composable нельзя будет пропустить (нельзя вывести). Есть исключение из правила: если в другом модуле включен компилятор Compose, стабильность в любом случае предполагается.

Это как-то связано с изменяемым/нестабильным аргументом people: List of PeopleView?

Да, концепция та же, здесь интерфейс List не гарантирует неизменности нижележащего списка (может быть MutableList), поэтому по умолчанию List не пропускаем и вызывает перекомпоновку при каждом обновлении состояния.

Полезно прочитать: compose-api-guidelines

Другие вопросы по теме