【问题标题】:Scala scope, initializationScala范围,初始化
【发布时间】:2015-08-14 12:43:15
【问题描述】:

想象以下 Java 类:

class Test
{
    private Button b;
    private Table t;

    public Test()
    {
        setupButton();
        setupTable();
    }

    private void setupButton()
    {            
        b = ...
        b.doAwesomeStuff();
        // ... more stuff going on
    }

    private void setupTable()
    {            
        t = ...
        t.attach(b); // Works, because b is in (class) scope
    }
}

Scala 中的相同代码:

class Test()
{
    setupButton();
    setupTable();

    private def setupButton(): Unit =
    {
        val button: Button = ...
    }

    private def setupTable(): Unit =
    {
        val table: Table = ...
        table.attach(button) // <--- error, because button is not in scope, obviously
    }
}

现在,当然有解决办法。

一个是“使用变量”:

class Test
{
    private var b: Button = _
    private var t: Table = _

    // ... Rest works now, because b and t are in scope, but they are vars, which is not necessary
}

另一个是“把所有东西放在一个方法中”,所以基本上合并 setupButton() 和 setupTable()。如果这些方法中发生的事情有点复杂,那就不行了。

另一种方法是给方法参数,例如:

private void setupTable(b: Button) {...}

我提出的所有解决方案似乎都不合适,第一个几乎总是(为什么要使用 var,如果您只需要一个 val?),而在大多数情况下是第二个。三分之二导致了不必要的代码,所以我们进入了我们需要的范围。

我确信我可以提出多种其他解决方案,但我问你:在这种情况下你会怎么做?

【问题讨论】:

    标签: java scala scope initialization


    【解决方案1】:

    重构setupXXX方法并返回创建的组件:

    val button = setupButton()
    val table = setupTable()
    

    或者没有辅助方法:

    val button = { // setup button
    }
    val table = {  // setup table
    }
    

    【讨论】:

    • 如果你只做一个按钮,那效果很好。但是如果我有一个名为“setupTableS()”的方法(见复数),那么我必须为每个表做一个吗? (没有辅助方法也一样)
    • @Teolha 如果您不能单独设置组件,您可以使用如下设置方法:val (table1, table2) = setupTables() 例如
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 2012-04-04
    • 2019-10-14
    • 2021-03-11
    相关资源
    最近更新 更多