android return kotlin 的非空字体

android return non-null typeface by kotlin

我正在练习将 java 代码转换为 Kotlin 代码:

class TypefaceProvider {
    companion object {
        private var tmpTypeface = Hashtable<String,Typeface>()
        @JvmStatic
        fun getTypeface(context : Context, dir : String, name : String) : Typeface {
            var createTypeface : Typeface? = tmpTypeface[name]
            if(createTypeface == null){
                createTypeface = try{
                    Typeface.createFromAsset(context.assets,"$dir/$name")
                } catch (e : Exception){
                    Log.e(TAG, "fail. msg:${e.message}")
                    Typeface.DEFAULT
                } finally {
                    tmpTypeface[name] = createTypeface 
                }
            }
            return createTypeface <--- wrong, type mismatch
        }
    }
}

我想return一个非空字体对象,

我已经检查过 createTypeface 不是 null

如何解决 return 类型不匹配问题?

我应该使用 return createTypeface!! 还是

createTypeface?:Typeface.DEFAULT(但 Typeface.DEFAULT 重复)

否则?

简短的回答是——如果您确定 createTypeface 确实不是 null,返回 createTypeface!! 是安全的。你在断言你知道是真实的事情。看来您正在这样做,所以 !! 在这种情况下应该可以正常工作。

一般来说,如果您希望 Kotlin 推断出某些东西不是 null,您需要确保永远不会将 null 作为它的可能值。您的示例的一个选择是将空检查折叠到 ?: 运算符 --

class TypefaceProvider {
    companion object {
        private var tmpTypeface = Hashtable<String, Typeface>()
        @JvmStatic
        fun getTypeface(context: Context, dir: String, name: String): Typeface {
            val createTypeface = tmpTypeface[name] ?: try {
                Typeface.createFromAsset(context.assets, "$dir/$name")
            } catch (e: Exception) {
                Log.e(TAG, "fail. msg:${e.message}")
                Typeface.DEFAULT
            }
            tmpTypeface[name] = createTypeface`
            return createTypeface
        }
    }
}

请注意,我们必须将 tmpTypeface[name] = createTypefacefinally 块中拉出。它会导致您的缓存始终保存 null 值(请参阅下面的@Alexy Romanov 的评论)。顺便说一句,我觉得最好不要把它放在 finally 块中,变量赋值中的 side-effect 看起来很奇怪。此外,我们不必给出 createTypeface 和显式类型,因为它可以被推断出来。

如果你想要更易读的东西,你可以将 loading/caching 逻辑分解成一个单独的方法 --

class TypefaceProvider {
    companion object {
        private var tmpTypeface = Hashtable<String, Typeface>()

        private fun loadTypeFace(context: Context, dir: String, name: String): Typeface {
            val typeface = try {
                Typeface.createFromAsset(context.assets, "$dir/$name")
            } catch (e: Exception) {
                Typeface.DEFAULT
            }
            tmpTypeface[name] = typeface
            return typeface
        }

        @JvmStatic
        fun getTypeface(context: Context, dir: String, name: String) = 
            tmpTypeface[name] ?: loadTypeFace(context, dir, name)
    }
}