如何为属性为val类型的Kotlin data class实例正确赋值
Kotlin中属性为val的不可变data class,不能在实例创建后修改属性值,符合规范的实现方式有两种:
方案一:先收集所有参数,一次性构造实例(推荐)
不可变对象的最佳实践是创建时就确定所有属性值,你可以先把各时段的Time、date值存在临时变量里,遍历完所有时段数据后再直接构造Day实例,完全不需要修改属性:
val days = ArrayList<Day>() val listOfDays = this .groupBy { it.getDayOfMonth() } .map { WeatherForDay(it.value) } .take(FIVE_DAYS_FORECAST) listOfDays.forEach { weatherForDay -> // 临时变量暂存各时段数据 var date: Int = 0 var night: Time? = null var morning: Time? = null var noon: Time? = null var evening: Time? = null weatherForDay.weather.forEach { weather -> val time = Time( weather.main.temp, weather.main.feels_like, weather.wind.speed, weather.wind.gust, weather.wind.deg, weather.main.pressure, ) // 匹配时段赋值给临时变量 when (weather.getTime()) { NIGHT_DAYTIME -> night = time MORNING_DAYTIME -> morning = time DAY_DAYTIME -> noon = time EVENING_DAYTIME -> evening = time } date = weather.dt } // 所有数据收集完成后一次性构造Day实例 days.add(Day(date, night, morning, noon, evening)) }
方案二:使用data class自带的copy方法分步构建
如果业务场景确实需要分步修改属性,可以用data class默认生成的copy方法,该方法会返回一个修改了指定属性的新实例,原实例保持不变:
listOfDays.forEach { var day = Day() it.weather.forEach { weather -> val time = Time( weather.main.temp, weather.main.feels_like, weather.wind.speed, weather.wind.gust, weather.wind.deg, weather.main.pressure, ) // 每次修改都生成新的Day实例 day = when (weather.getTime()) { NIGHT_DAYTIME -> day.copy(night = time) MORNING_DAYTIME -> day.copy(morning = time) DAY_DAYTIME -> day.copy(noon = time) EVENING_DAYTIME -> day.copy(evening = time) else -> day } day = day.copy(date = weather.dt) } days.add(day) }
该方案会生成多个中间实例,适合属性少、修改次数少的场景,性能不如一次性构造方案。
内容的提问来源于stack exchange,提问作者SoulReaver313
相关产品推荐
相关产品推荐

