【问题标题】:Why it is allowed to point to constructors parameters?为什么允许指向构造函数参数?
【发布时间】:2009-10-12 14:19:54
【问题描述】:

这段代码

class Foo(str: String) {
    val len = str.length
    def getLen = len
    def getStr = str}

将被编译为

public class Foo implements ScalaObject
{

    private final int len;
    private final String str;
    public Foo(String str)
    {
        this.str = str;
        super();
        len = str.length();
    }

    public String getStr()
    {
        return str;
    }

    public int getLen()
    {
        return len();
    }

    public int len()
    {
        return len;
    }

    public int $tag()
        throws RemoteException
    {
        return scala.ScalaObject.class.$tag(this);
    }
}

但是这段代码

class Foo(str: String) {
    val len = str.length
    def getLen = len
}

将被编译为

public class Foo implements ScalaObject
{

    private final int len;

    public Foo(String str)
    {
        len = str.length();
    }

    public int getLen()
    {
        return len();
    }

    public int len()
    {
        return len;
    }

    public int $tag()
        throws RemoteException
    {
        return scala.ScalaObject.class.$tag(this);
    }
}

为什么 Foo 类中没有私有成员?

private final String str;

这是某种优化吗?

为什么允许指向构造函数的参数。 为什么“def getStr = str”行没有编译时错误?

【问题讨论】:

  • +1 今天早上我问自己同样的事情:-)。

标签: scala


【解决方案1】:

在 Scala 中,构造函数参数在类中的任何位置都可见,我认为它更像是“对象参数”。在你的第二个 sn-p 中,它没有被编译为它创建一个类属性,仅仅是因为你没有在构造函数之外引用它——它是不需要的。

【讨论】:

  • 但是谁应该管理用作构造函数参数的对象的生命周期?
  • 我不确定我是否理解这个问题......因为通常对象可能在不存在引用时被 GC 处理。您的 Foo 类不管理该对象的生命周期(它在其他地方实例化,谁知道周围有多少引用)。编译只是确保在不需要时不保留引用。这可能会也可能不会使其成为 GC 候选者,这取决于其他地方正在做什么。
【解决方案2】:

好吧,根据 Odersky 的书,构造函数是唯一可以将字段与构造函数参数匹配的地方。如果你不这样做,在构造函数之外将看不到任何变量。

【讨论】:

    猜你喜欢
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多