【问题标题】:Is there even a simpler way to express anonymous classes in Kotlin?在 Kotlin 中表达匿名类还有更简单的方法吗?
【发布时间】:2016-09-19 08:47:55
【问题描述】:

我翻译了这个Java

new Thread("Cute Thread") {
  public void run() {
    int a = 3;
  }
}.start();

到这个 Kotlin

object : Thread("Cute Thread") {
  override fun run() {
     val a = 3
  }
}.start()

但是我觉得有一种更简单的方法可以做到这一点,但是我找不到任何示例。

我试过了

  Thread("Cute Thread") { val a = 3 }.start()

但是没有成功...

附言。我知道像这样启动线程是一种不好的做法。

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    实现匿名类没有不同的方法(SAM conversions 除外)。
    但是您仍然可以通过以下方式简化代码:

     Thread({ val a = 3 }).start()
    

    或使用线程名称:

    Thread({ val a = 3 }, "Cute Thread").start()
    

    【讨论】:

    • 您没有提供问题的解决方案(匿名类语法),而是使用Thread 类的不同方式。
    • @nhaarman 你确定他的问题是关于更短的匿名类还是更短的代码?如果你是一个纯粹的主题主义者,你是对的,但如果你努力理解他的真实意图,你可能会错:But I feel that there is a simpler way of doing this, however I can't find any examples.
    • 是的,我的目标是缩短代码,谢谢!抱歉,如果我的问题不清楚。我完全赞成减少代码,只要它不影响可读性。这是我从 Java 转到 Kotlin 的主要原因。
    • @PedroD 你说的是PS. I know that starting a Thread like this is a bad practice。这个答案克服了不好的做法,您不再从 Thread 继承,而是将 Runnable 传递给构造函数。
    • Thread继承也被认为是一种不好的做法吗?我指的不好的做法是创建一个无头线程。 IE。从那一刻起,我将无法控制该线程的生命周期,因为我没有对它的引用。按照惯例,我应该保留我所有线程的列表。
    【解决方案2】:

    这里的一个问题是Thread 类构造函数的参数顺序对 Kotlin 不正确。对于Runnable,您可以轻松使用SAM conversion单个方法接口可以被视为 lambda),但由于 lambda 不是最后一个参数,它看起来有点笨拙。如果只有一个参数就可以了:

    Thread { val a = 3 }.start()
    

    但是,如果有多个参数,它们会向后导致这种丑陋的语法,其中 lambda 作为括号内的参数:

    Thread({ val a = 3 }, "some name").start()
    

    您应该使用 Kotlin 标准库函数 thread()

    使用该函数,您可以使用更简单的语法:

    // create thread, auto start it, runs lambda in thread
    thread { val a = 3 }  
    
    // create thread with given name, auto start it, runs lambda in thread
    thread(name = "Cute Thread") { val a = 3 }  
    
    // creates thread that is paused, with a lambda to run later
    thread(false) { val a = 3 } 
    
    // creates thread that is paused with a given name, with a lambda to run later
    thread(false, name = "Cute Thread") { val a = 3 } 
    

    另见:thread() function documentation

    【讨论】:

    • 太棒了!谢谢!
    • @PedroD 答案已现代化
    • 这对thread 来说很好,因为它已经存在,但是我如何创建自己的实现来允许更短的版本呢?例如一些简单的接口interface OnResultCallback{ fun onSuccess(result: SomeResultClass) }
    • @androiddeveloper 请创建一个新问题,因为您的问题与该特定问题无关。另请参阅最新 Kotlin 版本中的“用于 Kotlin 接口的 SAM 转换”。
    • @JaysonMinard 我不记得我为什么问这个了,但我认为答案是“有趣的界面”。
    【解决方案3】:

    您的代码绝对正确。简化它的唯一方法是将逻辑提取到一个函数中,然后重用它:

    fun newThread(name: String, block: () -> Unit): Thread {
        return object : Thread(name) {
            override fun run() = block()
        }.start()
    }
    

    用法:

    newThread("Cute Thread") {
        val a = 3
    }
    

    【讨论】:

    【解决方案4】:

    如果你想在你的匿名类中扩展/实现一些类/接口,别无他法:

    object: Thread("Name"){
        //...
    }.start()
    

    最简单的结构当然是:

    val adhoc = object{
        // some code here
    }
    

    但没有更简单的方法可以做到这一点。

    Documentation,但你可能读过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多