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

同样,仅当ifholder时,才会运行NewsViewHolder子句中的代码,因此允许您在该范围内将holder用作NewsViewHolder,尤其是调用此类型的函数。

10-08 17:51