ต่อไปนี้เป็นรูปแบบบางส่วนขึ้นอยู่กับว่าคุณต้องการใช้สไตล์ใดหากคุณมีทุกอย่างเหมือนกันหรือต่างกันและหากไม่ทราบจำนวนรายการ ...
ประเภทผสมทั้งหมดต้องไม่เป็นค่าว่างเพื่อคำนวณค่าใหม่
สำหรับประเภทผสมคุณสามารถสร้างชุดฟังก์ชันสำหรับการนับพารามิเตอร์แต่ละตัวที่อาจดูไร้สาระ แต่ใช้ได้ดีกับประเภทผสม:
inline fun <T1: Any, T2: Any, R: Any> safeLet(p1: T1?, p2: T2?, block: (T1, T2)->R?): R? {
return if (p1 != null && p2 != null) block(p1, p2) else null
}
inline fun <T1: Any, T2: Any, T3: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, block: (T1, T2, T3)->R?): R? {
return if (p1 != null && p2 != null && p3 != null) block(p1, p2, p3) else null
}
inline fun <T1: Any, T2: Any, T3: Any, T4: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, p4: T4?, block: (T1, T2, T3, T4)->R?): R? {
return if (p1 != null && p2 != null && p3 != null && p4 != null) block(p1, p2, p3, p4) else null
}
inline fun <T1: Any, T2: Any, T3: Any, T4: Any, T5: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, p4: T4?, p5: T5?, block: (T1, T2, T3, T4, T5)->R?): R? {
return if (p1 != null && p2 != null && p3 != null && p4 != null && p5 != null) block(p1, p2, p3, p4, p5) else null
}
// ...keep going up to the parameter count you care about
ตัวอย่างการใช้งาน:
val risk = safeLet(person.name, person.age) { name, age ->
// do something
}
ดำเนินการบล็อกรหัสเมื่อรายการไม่มีรายการว่าง
สองรสชาติที่นี่อันดับแรกจะดำเนินการบล็อกโค้ดเมื่อรายการมีรายการที่ไม่ใช่ค่าว่างทั้งหมดและอย่างที่สองจะทำเช่นเดียวกันเมื่อรายการมีอย่างน้อยหนึ่งรายการที่ไม่ใช่รายการว่าง ทั้งสองกรณีส่งผ่านรายการที่ไม่ใช่ค่าว่างไปยังบล็อกของรหัส:
ฟังก์ชั่น:
fun <T: Any, R: Any> Collection<T?>.whenAllNotNull(block: (List<T>)->R) {
if (this.all { it != null }) {
block(this.filterNotNull()) // or do unsafe cast to non null collectino
}
}
fun <T: Any, R: Any> Collection<T?>.whenAnyNotNull(block: (List<T>)->R) {
if (this.any { it != null }) {
block(this.filterNotNull())
}
}
ตัวอย่างการใช้งาน:
listOf("something", "else", "matters").whenAllNotNull {
println(it.joinToString(" "))
} // output "something else matters"
listOf("something", null, "matters").whenAllNotNull {
println(it.joinToString(" "))
} // no output
listOf("something", null, "matters").whenAnyNotNull {
println(it.joinToString(" "))
} // output "something matters"
การเปลี่ยนแปลงเล็กน้อยเพื่อให้ฟังก์ชันรับรายชื่อรายการและดำเนินการแบบเดียวกัน:
fun <T: Any, R: Any> whenAllNotNull(vararg options: T?, block: (List<T>)->R) {
if (options.all { it != null }) {
block(options.filterNotNull()) // or do unsafe cast to non null collection
}
}
fun <T: Any, R: Any> whenAnyNotNull(vararg options: T?, block: (List<T>)->R) {
if (options.any { it != null }) {
block(options.filterNotNull())
}
}
ตัวอย่างการใช้งาน:
whenAllNotNull("something", "else", "matters") {
println(it.joinToString(" "))
} // output "something else matters"
let()
การเปลี่ยนแปลงเหล่านี้อาจมีการเปลี่ยนแปลงที่จะมีค่าที่ส่งคืนเช่น
ใช้รายการแรกที่ไม่ใช่ค่าว่าง (Coalesce)
คล้ายกับฟังก์ชัน SQL Coalesce ส่งคืนรายการแรกที่ไม่ใช่ค่าว่าง ฟังก์ชั่นสองรสชาติ:
fun <T: Any> coalesce(vararg options: T?): T? = options.firstOrNull { it != null }
fun <T: Any> Collection<T?>.coalesce(): T? = this.firstOrNull { it != null }
ตัวอย่างการใช้งาน:
coalesce(null, "something", null, "matters")?.let {
it.length
} // result is 9, length of "something"
listOf(null, "something", null, "matters").coalesce()?.let {
it.length
} // result is 9, length of "something"
รูปแบบอื่น ๆ
... มีรูปแบบอื่น ๆ แต่หากมีข้อกำหนดมากกว่านี้อาจทำให้แคบลงได้