【问题标题】:kotlin access property of anonymous object匿名对象的kotlin访问属性
【发布时间】:2019-05-07 19:53:29
【问题描述】:

如何访问匿名对象的属性word

 fun main(args: Array<String>) {

        val sentence = "this is a nice sentence"

        val wordLengths: List<Any> = sentence.split(' ').map {
            object {
                val length = it.length
                val word = it
            }
        }

        wordLengths.forEach { it:Any -> println(it) }
    }

【问题讨论】:

  • 您定义了一个类并使用该类而不是使用 Any?
  • 是的..我想知道为什么他们允许我优雅地创建一个object,然后不给我访问属性的方法..
  • 请清楚描述您的问题。
  • 是什么阻止你使用wordLengths.forEach { println(it.word) }
  • 就是这样。它不会编译..

标签: kotlin


【解决方案1】:

您将wordLengths 明确声明为List&lt;Any&gt;,而Any 没有wordlength 属性。您应该让 Kotlin 从 map 推断类型。

fun main() {
    val sentence = "This is a nice sentence"

    val wordLengths = sentence.split(' ').map {
        object {
            val word = it
            val length = it.length
        }
    }

    wordLengths.forEach {
        println("[${it.length}] ${it.word}")
    }
}

如果你打算在方法之外需要这个对象,那么你应该创建必要的类或使用现有的类(例如PairString 本身)。见Object expressions

请注意,匿名对象只能在本地和私有声明中用作类型。如果您使用匿名对象作为公共函数的返回类型或公共属性的类型,则该函数或属性的实际类型将是匿名对象的声明超类型,或者 Any 如果您没有声明任何超类型。添加到匿名对象中的成员将无法访问。

【讨论】:

    【解决方案2】:

    这可以按预期工作——但这​​可能不是一个好方法。

    直接的问题是代码将wordLengths 的类型指定为List&lt;Any&gt;Any 是顶级类型*;每种类型都是它的子类型,因此您只能安全地访问每种类型拥有的东西(例如toString() 方法)。

    但是,您不需要指定类型;你可以把它留给 Kotlin 的类型推断。如果您这样做,它会推断您使用 object 关键字定义的类型。这种类型是匿名的——你不能写下它的名字——但 Kotlin 知道它,并且可以访问它的字段:

    fun main() {
        val sentence = "this is a nice sentence"
    
        val wordLengths = sentence.split(' ').map {
            object {
                val length = it.length
                val word = it
            }
        }
    
        wordLengths.forEach{ println(it.word) }
    }
    

    也就是说,它有点尴尬和脆弱。您最好为该类型定义一个类。事实上,总体而言,这更短:

    fun main2() {
        val sentence = "this is a nice sentence"
    
        class Word(val length: Int, val word: String)
    
        val wordLengths = sentence.split(' ').map{ Word(it.length, it) }
    
        wordLengths.forEach { println(it.word) }
    }
    

    (实际上,您可能希望在其他地方使用新类,并将其移到方法之外。但 Kotlin 允许您在需要时定义本地类。)

    ——

    (* 实际上,顶级类型是可为空的 Any:Any?。但我忽略了可空性,因为它与此无关。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-31
      • 2012-11-17
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多