The following Code A is from the main branch of the official sample project.
In Code A, two 'it' are deduced as Account
type , and also 'account' is deduced as Account
type.
How can Kotlin deduce? You know private fun <T> OverviewScreenCard(...)
is generic , and T
maybe is any type.
BTW, I think that I should use Code B instead of Code A.
Code A
@Composable
private fun AccountsCard(onClickSeeAll: () -> Unit, onAccountClick: (String) -> Unit) {
val amount = UserData.accounts.map { account -> account.balance }.sum()
OverviewScreenCard(
title = stringResource(R.string.accounts),
amount = amount,
onClickSeeAll = onClickSeeAll,
data = UserData.accounts,
colors = { it.color }, // This 'it' is Account type
values = { it.balance } // This 'it' is Account type
) { account -> // This 'account' is Account type
AccountRow(
modifier = Modifier.clickable { onAccountClick(account.name) },
name = account.name,
number = account.number,
amount = account.balance,
color = account.color
)
}
}
@Composable
private fun <T> OverviewScreenCard(
title: String,
amount: Float,
onClickSeeAll: () -> Unit,
values: (T) -> Float,
colors: (T) -> Color,
data: List<T>,
row: @Composable (T) -> Unit
) {
...
}
@Composable
fun AccountRow(
modifier: Modifier = Modifier,
name: String,
number: Int,
amount: Float,
color: Color
) {
...
}
Code B
@Composable
private fun AccountsCard(onClickSeeAll: () -> Unit, onAccountClick: (String) -> Unit) {
val amount = UserData.accounts.map { account -> account.balance }.sum()
OverviewScreenCard<Account>( //I think I need use this
title = stringResource(R.string.accounts),
...
) { account ->
...
}
}
CodePudding user response:
Indeed, none of the parameters you have passed to OverviewScreenCard
constrains T
in any way, except
data = UserData.accounts
UserData.accounts
is of type List<Account>
. On the right hand side, the data
parameter is expecting a List<T>
. This constrains what T
can be. T
can only be Account
, or a super type of Account
. Otherwise, you wouldn't have been able to pass UserData.accounts
to the data
parameter.
And since the other parameters you have passed does not constrain the type of T
further, the compiler resolves the constraints on T
and chooses the most specific type that satisfies them, which is Account
.
You can also specify the type directly like you do in Code B, but it is redundant.