2017-03-09 70 views
2

讓說,我有翻譯撲克牌信整數科特林地圖與非NULL值

val rank = mapOf("J" to 11, "Q" to 12, "K" to 13, "A" to 14) 

當與地圖工作的Map似乎我總是不得不做出一個空安全檢查即使地圖和對不可改變:

val difference = rank["Q"]!! - rank["K"]!! 

我想這來自於通用的類型都沒有?超類型。爲什麼不能在編譯時解決Map和Pair都不可變的問題?

+0

使用'value'屬性可能是優選的清潔器代碼的枚舉。這裏有一個快速的語法示例:http://pastebin.com/1BtynHMN –

回答

8

這不是關於Map的實現(基於Kotlin或Java)。您正在使用Map並且地圖可能沒有關鍵字,因此[]運算符返回可爲null的類型。

+0

Ofcourse!如果鍵不存在於映射中,則返回值爲空。 –

2

mapOf()提供的Map並不保證密鑰的存在 - 這是一種特別考慮Map的Java實現的期望。雖然我個人更喜歡堅持使用空安全調用和elvis操作符,但聽起來像您希望在調用站點使用更乾淨的代碼(特別是考慮到您知道這些鍵存在且具有關聯的非空值)。考慮一下:

class NonNullMap<K, V>(private val map: Map<K, V>) : Map<K, V> by map { 
    override operator fun get(key: K): V { 
     return map[key]!! // Force an NPE if the key doesn't exist 
    } 
} 

通過委託給map的實現,但是覆蓋get方法,我們可以保證返回值是非空的。這意味着您不再需要擔心!!,?,或?:您的用例。

某些簡單的測試代碼顯示這是真的:

fun main(args: Array<String>) { 
    val rank = nonNullMapOf("J" to 11, "Q" to 12, "K" to 13, "A" to 14) 
    val jackValue: Int = rank["J"] // Works as expected 
    println(jackValue) 
    val paladinValue: Int = rank["P"] // Throws an NPE if it's not found, but chained calls are considered "safe" 
    println(jackValue) 
} 

// Provides the same interface for creating a NonNullMap as mapOf() does for Map 
fun <K, V> nonNullMapOf(vararg pairs: Pair<K, V>) = NonNullMap(mapOf<K, V>(*pairs))