从kotlin文档中我不清楚as运算符

时间:2017-09-24 16:17:21

标签: android android-recyclerview kotlin

documentation对我来说真的很神秘

  

通常,如果无法进行强制转换,则强制转换运算符会抛出异常。 >因此,我们称之为不安全。 Kotlin中的不安全强制转换是由中缀运算符>完成的(参见运算符优先级):

     

val x:String = y as String

因为" 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

在同一个类中有一个内部类
  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为什么变量持有者应该指向内部类的方法,这对我来说真的很困惑。我宁愿做完 val holderOther = NewsViewHolder.bind(item)

1 个答案:

答案 0 :(得分:3)

删除行holder as NewsViewHolder影响以下行的原因是smart casting

每当您的代码检查类型或执行as - 强制转换时,Kotlin编译器会分析控制流,如果变量不能及时更改,编译器允许您使用该点上的变量作为如果它的类型是您检查的类型。

在您的示例中,holder as NewsViewHolder检查函数参数是否为NewsViewHolder。鉴于(1)函数参数不能被重新赋值,(2)只有当holder实际上是NewsViewHolder时函数才会继续执行(否则会抛出异常),编译器会处理{{1在函数的其余部分中作为holder

这反过来允许您在NewsViewHolder上调用fun bind(item: RedditNewsItem),而无需另外显式演员或使用单独的变量。

智能演员尊重holder - 演员和as - 支票。您可以改为编写它(虽然更改了原始代码的语义):

is

同样,if (holder is NewsViewHolder) { holder.bind(item as RedditNewsItem) } 子句中的代码仅在ifholder时才会运行,因此您可以NewsViewHolder作为holder在该范围内,特别是调用此类型的函数。