智能转换为 'Bitmap!' 是不可能的,因为 'textBitmap' 是一个由变化的闭包捕获的局部变量

Smart cast to 'Bitmap!' is impossible, because 'textBitmap' is a local variable that is captured by a changing closure

每当我构建我的项目时,我都会遇到这个错误

这里是 kotlin class 代码

var textBitmap: Bitmap? = null
dynamicItem.dynamicText[imageKey]?.let { drawingText ->
            dynamicItem.dynamicTextPaint[imageKey]?.let { drawingTextPaint ->
drawTextCache[imageKey]?.let {
                    textBitmap = it
                } ?: kotlin.run {
                    textBitmap = Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888)
                    val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
                    val textCanvas = Canvas(textBitmap)
                    drawingTextPaint.isAntiAlias = true
                    val fontMetrics = drawingTextPaint.getFontMetrics();
                    val top = fontMetrics.top
                    val bottom = fontMetrics.bottom
                    val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
                    textCanvas.drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
                    drawTextCache.put(imageKey, textBitmap as Bitmap)
                }

我不知道如何修复它

与其像那样嵌套 let,我更愿意做一些保护子句

val drawingText = dynamicItem.dynamicText[imageKey] ?: return // or you could assign an empty string `?: "" `
val drawingTextPaint = dynamicItem.dynamicTextPaint[imageKey] ?: return
val textBitmap: Bitmap = drawTextCache[imageKey] ?: Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888).applyCanvas {
   val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
   val fontMetrics = drawingTextPaint.getFontMetrics()
   val top = fontMetrics.top
   val bottom = fontMetrics.bottom
   val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
   drawingTextPaint.isAntiAlias = true
   drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
}
drawTextCache.put(imageKey, textBitmap)

基本上,Kotlin 无法在该 lambda 中将 textBitmap 智能转换为 non-null Bitmap。您可能在 Canvas(textBitmap) 调用中遇到错误,它不能接受 null 参数,并且编译器无法保证 textBitmap 在那一刻不为 null。

这是可以更改的 lambda 引用外部 vars 的限制 - 我认为这是因为 lambda 可能在其他时间是 运行,所以不能保证什么是发生在那个外部变量上,以及是否有其他东西可以修改它。具体的我就不知道了,大家有空一起聊

修复非常简单,如果您所做的只是创建一个 textBitmap 变量并为其赋值:

// Assign it as a result of the expression - no need to create a var first and keep
// changing the value, no need for a temporary null value, it can just be a val
val textBitmap: Bitmap? =
    dynamicItem.dynamicText[imageKey]?.let { drawingText ->
        dynamicItem.dynamicTextPaint[imageKey]?.let { drawingTextPaint ->
            drawTextCache[imageKey]
            ?: Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888).apply {
                    val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
                    val textCanvas = Canvas(this)
                    drawingTextPaint.isAntiAlias = true
                    val fontMetrics = drawingTextPaint.getFontMetrics();
                    val top = fontMetrics.top
                    val bottom = fontMetrics.bottom
                    val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
                    textCanvas.drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
                    drawTextCache.put(imageKey, this)
            }
        }
    }   

我建议将位图创建部分分解成它自己的函数以提高可读性,并且我个人会避免嵌套 lets(因为在什么情况下你得到的东西不是很明显)但是这是一种风格选择