构造函数参数在整个类中可见——是一种特性还是一个错误?

11 浏览
0 Comments

构造函数参数在整个类中可见——是一种特性还是一个错误?

考虑以下代码(这只是一个示例,不是真正的代码):

class Foo(url : String) extends Bar(url)
{
  def say() { println(url) }
}

它可以编译并且可以运行。当然,结果是无意义的。我太新手来判断,但对我来说,它没有任何意义,只会造成困惑 - 根据定义,构造函数的参数不可能直接在另一个方法中被访问到。

有经验的Scala用户能否指出可能使其起作用或有意义的条件?或者确认我怀疑这是当前Scala编译器的缺陷。

更新

class Bar(val Url : String)

{

}

为什么说是“无意义”的呢?因为我想要的(Foo中没有“var”和“val”)仅仅是传递参数,没有其他目的。因此,当我真正使用构造函数参数时,只是意味着我<强>错误地使用了某个实体。如果你故意写,每次都会命中,但如果你不这样做(例如,你在拼写上犯了错误),你就是随机使用实体。这不是代码没有意义,而是计算本身没有意义,我也可以掷骰子。方法有作用域,我不明白为什么构造函数不应该有作用域。

更新 - 解决方法

所以看起来这个错误的构造确实是语言的一部分(设计如此)。正如UserUnknown和Tomasz Nurkiewicz建议的,防止犯傻的拼写错误的唯一方法是约定,但是大小写不好区分。大写字母"A"和小写字母"a"差别很大,但大写字母"U"和小写字母"u"差别不大。引入一个特殊字符(如Tomasz所示)更好,因为可以从视觉上检测到构造函数参数的可疑用法。

我将使用"$"表示“仅传递”构造函数参数,这对我来说更难输入,并且在代码中不经常见到这个字符。

感谢回答!

为什么它是错误的?因为隐式操作应该由用户明确地允许 - 好的例子是C#中的“dynamic”,Scala中的隐式转换。而导致大量问题的违反此规则的例子有 - C++中的隐式转换为bool,C++中的隐式构造函数,Perl中的按使用进行声明。这个特殊情况非常接近上述的perlism,在Perl中最终更改了解释器以检测此类错误用法,为什么Scala会重复同样的错误?我想知道。

0
0 Comments

(Constructor arguments are visible in entire class -- a feature or a bug?)这个问题的出现的原因是Scala在类中的方法引用构造函数参数时会创建一个字段。这导致在整个类中都可以访问构造函数参数,这可能被一些人认为是一个功能,也可能被一些人认为是一个bug。在上述的例子中,尽管构造函数参数的大小写不同,但依然可以正常工作,这是因为编译器能够智能地去获取父类中的字段的值。然而,如果在类中误拼了一个var字段,就会引入一个新的字段,并且这两个字段可能会不一致。这种情况下,Scala并没有提供任何帮助来防止这种错误,除了依赖命名约定。有些人认为构造函数参数应该只是参数,如果希望它们在整个类中可见,可以将它们声明为类字段。因此,有人建议Scala应该提供一些方式来防止这种错误,比如使用关键字来明确表示构造函数参数。

0
0 Comments

(Constructor arguments are visible in entire class -- a feature or a bug?)

构造函数参数在整个类中可见是一个特性还是一个bug?这个问题的出现的原因是构造函数参数可以在整个类中被访问,这是Scala语言的一个特性。在Scala中,构造函数参数的可见性更广泛,它们可以被整个类的方法访问和使用。这种设计可以方便地在类的其他方法中使用构造函数参数。

然而,这个特性也可能会导致一些问题。例如,在使用Scala类作为Hibernate实体时,如果在基类中使用构造函数参数而不是字段,就会出现重复字段的问题。这可能会导致运行时出现Hibernate报错,指出定义了重复的列映射。因此,这种特性可能会导致混淆和错误,并且可能会增加代码的错误风险。

为了解决这个问题,可以通过在构造函数参数上添加"val"修饰符来将其声明为字段,而不是只作为构造函数参数。这样可以明确地将构造函数参数转换为类的字段,避免混淆和错误。

,构造函数参数在整个类中可见是Scala语言的一个特性,它可以方便地在类的其他方法中使用。然而,这个特性也可能导致混淆和错误,因此在使用时需要小心处理。解决方法是将构造函数参数声明为字段,以明确它们的作用和可见性。

0
0 Comments

(Constructor arguments are visible in entire class -- a feature or a bug?)

在上述内容中,提到了关于构造函数参数在整个类中可见的问题。这个问题的出现原因是因为在设计中,类的参数是类的一部分,如果有必要,它们会作为字段被保留(例如在您的示例中),如果它们从未在构造函数之外使用,那么它们就不会被保留。

所以,基本上,如果你不需要它作为字段,它就不会成为字段。如果你需要,它就会成为字段。而且,你不需要写一行额外的代码告诉编译器它可以自己找出来。

嗯,在上述示例中,它导致了荒谬的结果,所以它有点像“如果这可能导致错误的程序,编译器自动允许它”。换句话说,我希望禁止这种自动字段的情况,因为显然我只是调用了基类构造函数+我写错了一个字母。

解决这个问题的方法是在构造函数中显式地声明字段,以避免编译器自动创建字段。以下是一个示例:

class BaseClass

{

private int _field;

public BaseClass(int field)

{

_field = field;

}

}

class DerivedClass : BaseClass

{

public DerivedClass(int field) : base(field)

{

}

}

在这个示例中,我们通过在基类的构造函数中显式地声明了一个私有字段来避免编译器自动创建字段。这样,我们就可以确保参数只在构造函数中可见,而不会在整个类中被访问。

0