documentation对我来说真的很神秘
因为在互联网引擎中不容易找到“as”一词,所以我无法理解作为的用法,并且与运营商相关的方式是
给出以下代码:
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) {
holder as NewsViewHolder//why is not called holder2 considering is adressed to NewsViewHolder?
holder.bind(item as RedditNewsItem)
}
如果我摆脱了NewsViewHolder,则intelliJ点将绑定(bind)为红色。原因是因为在同一个类中有一个内部类具有方法bind
inner class NewsViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
parent.inflate(R.layout.news_item)) {
private val imgThumbnail = itemView.img_thumbnail
private val description = itemView.description
private val author = itemView.author
private val comments = itemView.comments
private val time = itemView.time
fun bind(item: RedditNewsItem) {
imgThumbnail.loadImg(item.thumbnail)
description.text = item.title
author.text = item.author
comments.text = "${item.numComments} comments"
time.text = item.created.getFriendlyTime()
super.itemView.setOnClickListener { viewActions.onItemSelected(item.url)}
}
}
但是我在评论中指出,如果方法将持有人与类Recycler.ViewHolder传递,为什么将变量持有人指向内部类的方法,这确实让我感到困惑。我宁愿做
valholderOther = NewsViewHolder.bind(item)
最佳答案
删除行holder as NewsViewHolder
会影响下面的行的原因是smart casting。
每当您的代码检查类型或执行as
-cast时,Kotlin编译器都会分析控制流,如果变量无法及时更改,则编译器允许您从那时起使用该变量,就好像它的类型就是您所使用的一样。检查。
在您的示例中,holder as NewsViewHolder
检查功能参数是否为NewsViewHolder
。鉴于(1)无法重新分配功能参数,以及(2)仅当holder
实际上是NewsViewHolder
(否则将引发异常)时,该函数将继续执行,编译器在其余函数中将holder
视为NewsViewHolder
。
反过来,这允许您调用fun bind(item: RedditNewsItem)
上的holder
,而无需其他显式强制转换或使用单独的变量。
智能转换会同时遵守as
-cast和is
-checks。您可以这样写(尽管更改了原始代码的语义):
if (holder is NewsViewHolder) {
holder.bind(item as RedditNewsItem)
}
同样,仅当
if
为holder
时,才会运行NewsViewHolder
子句中的代码,因此允许您在该范围内将holder
用作NewsViewHolder
,尤其是调用此类型的函数。