android通过kotlin返回非null字体

时间:2018-04-11 03:23:46

标签: java android kotlin android-typeface

我正在练习将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
        }
    }
}

我想返回一个非null的字体对象,

我已检查createTypeface不是null

如何修复返回类型不匹配问题?

我应该使用return createTypeface!!还是

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

或其他?

1 个答案:

答案 0 :(得分:2)

简短的回答是 - 如果您确定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] = createTypeface拉出finally块。它会使您的缓存始终保存null值(请参阅下面的@Alexy Romanov评论)。顺便说一句,我觉得最好不要在finally块中使用它,变量赋值中的副作用似乎很奇怪。此外,我们不必提供createTypeface和显式类型,因为它可以推断出来。

如果您想要更具可读性的东西,可以将加载/缓存逻辑分解为单独的方法 -

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)
    }
}