37. val と var
val はgetterのみで再代入できない(read-only)
var はgetterとsetterがあり再代入できる(mutable)
val a = 0
var b = 0
a = 1 // NG
b = 1 // OK
38. List と MutableList
List は要素を変更するメソッドがない(read-only)
MutableList は要素を変更するメソッドがある(mutable)
val a = listOf(1, 2, 3)
val b = mutableListOf(1, 2, 3)
a.add(4) // NG
b.add(4) // OK
45. ある時点を過ぎると値が確定し、不変だ
値は変わらないのに var で、しかもNullable
class MainActivity : AppCompatActivity() {
var articleId: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
articleId = intent.getStringExtra(ARTICLE_ID)
}
}
46. ある時点を過ぎると値が確定し、不変だ
lazy で書くと val かつNonNullにできる
class MainActivity : AppCompatActivity() {
val articleId: String by lazy {
intent.getStringExtra(ARTICLE_ID)
}
}
66. 2つのリストを同時に扱う
val nameList = listOf("Alice", "Bob", "Charlie")
val ageList = listOf(20, 25, 30)
val size = minOf(nameList.size, ageList.size)
for (i in 0 until size) {
val name = nameList[i]
val age = ageList[i]
println("$name($age)")
}
67. 2つのリストを同時に扱う:zip
val nameList = listOf("Alice", "Bob", "Charlie")
val ageList = listOf(20, 25, 30)
nameList.zip(ageList) { name, age ->
println("$name($age)")
}
70. 変換と除外
val ids = listOf(...)
val fruits = mutableListOf<Fruit>()
for (id in ids) {
for (fruit in Fruit.values()) {
if (fruit.id == id) {
fruits.add(fruit)
}
}
}
return fruits
75. リストをN個ずつに分割
val idList = 'A'..'Z'
val charList = mutableListOf<MutableList<Char>>()
val count = idList.count()
for (i in 0 until count) {
if (i % 10 == 0) {
charList.add(mutableListOf())
}
charList.last().add(idList.elementAt(i))
}
return charList // [[A,B,……,J],[K,L,……,T],[U,V,……,Z]]
94. Nullable と NonNull
KotlinといえばNullabilityが嬉しい
val nullable: String? = null // OK
val nonNull: String = null // NG
nullable.length // NG
nullable!!.length // OK
nullable?.length // OK
nonNull.length // OK
117. そのままdata classにすると
検索条件はこんな感じに → data class SearchCondition(
val area: Area?,
val station: Station?,
val location: Location?,
val query: String?,
val menu: Menu?,
val price: Price?
// ...
)
118. 「ありえない状態」ができてしまう
【ビジネスロジック】
● エリア/駅/緯度経度は排他
○ でもいずれか1つは必須
● 料金はメニュー指定時のみ
● etc……
data class SearchCondition(
val area: Area?,
val station: Station?,
val location: Location?,
val query: String?,
val menu: Menu?,
val price: Price?
// ...
)
137. 状態数の分析
1. Kotlinを数式に変換する
2. 数式を展開する
3. ありえない項を削除する
4. 残った項をまとめる
5. 数式をKotlinに戻す
6. 適宜 sealed class や data class を使って意味付けをする
data class Target(
val abc: Either<Pair<A, B?>, C>?
)