gre*_*man 1 constructor scope arguments scala
考虑这样的代码(这只是示例而不是真正的代码):
class Foo(url : String) extends Bar(url)
{
def say() { println(url) }
}
Run Code Online (Sandbox Code Playgroud)
它编译并且有效.无意义的结果"当然".我太新手无法判断,但对我而言,它没有任何意义,只有混乱 - 根据定义,构造函数的参数不可能直接在另一种方法中获得.
有人在Scala中有更多经验可以指出它可能有效还是有意义的条件?或者确认我怀疑这是当前Scala编译器中的缺陷.
更新
class Bar(val Url : String)
{
}
Run Code Online (Sandbox Code Playgroud)
为什么"胡说八道".因为我的遗嘱(在Foo中没有"var"和"val")只是传递参数,没有别的.因此,当我实际使用构造函数参数时,我只是错误地使用了什么实体.当你故意写作时,你每次都会获得累积奖金,但如果你没有(即拼写错误),你可以随机使用实体.这不是代码没有意义,它是计算只是没有意义,我也可以掷骰子.有一个方法范围,我没有看到为什么不应该有构造函数范围的原因.
所以这个邪恶的构造似乎真的是语言的一部分(按设计).正如UserUnknown和Tomasz Nurkiewicz所说,反对制作愚蠢错字的唯一防线就是惯例,但是低于大写的情况并不好."A"和"a"差别很大,但"U"和"u"并不多.引入一个特殊字符(如Tomasz所示)要好得多,因为可以直观地检测构造函数参数的可疑用法.
我将使用"$"作为"只传递"构造函数参数,为我输入更难,并且您在代码中不会经常看到此字符.
谢谢你的答案!
为什么它是邪恶的?因为用户应该明确允许隐式操作 - 好的例子在C#中是"动态的",在Scala中是隐式转换.打破这个导致大量问题的规则的例子是 - 在C++中隐式转换为bool,在C++中隐式构造函数,在Perl中使用声明.而这个特殊情况非常非常接近所提到的perlism,在Perl中,最终解释器发生了变化以检测这种错误,为什么Scala重复了同样的错误?我想知道.
Dan*_*ral 12
你的怀疑完全没有价值.这是设计的.
类的参数是类的一部分.如有必要,它们将作为字段保存(例如在您的示例中),如果它们从未在构造外使用,则不会保留.
所以,基本上,如果你不需要它作为一个领域,它将不会.如果你这样做,它会.而且你永远不会写一个额外的代码字符来告诉编译器它可以自己解决什么.
这不是一个错误,这是一个功能.事实上,一个非常好的.需要一个例子它有多大用处?以下是我如何通过构造函数将它与Spring和依赖注入一起使用:
@Service
class Foo @Autowired() (bar: Bar, jdbcOperations: JdbcOperations) {
def serverTime() = bar.format(jdbcOperations.queryForObject("SELECT now()", classOf[Date]))
}
Run Code Online (Sandbox Code Playgroud)
Java中的等效代码:
@Service
public class Foo
{
private final Bar bar;
private final JdbcOperations jdbcOperations;
@Autowired
public Foo(Bar bar, JdbcOperations jdbcOperations)
{
this.bar = bar;
this.jdbcOperations = jdbcOperations;
}
public String serverTime()
{
return this.bar.format(this.jdbcOperations.queryForObject("SELECT now()", Date.class));
}
}
Run Code Online (Sandbox Code Playgroud)
还是不相信?
简短教程:
class Foo(var x: Int, val y: Int, z: Int) {
println(z)
//def zz = z
}
Run Code Online (Sandbox Code Playgroud)
x将成为一个var有吸气剂和二传手的人.y将成为一个不可变的变量,并且z只有在zz取消注释方法时才会成为不可变的变量.否则它将仍然是构造函数参数.整齐!
更新:我现在明白你的意思了!通过访问url基类中的变量,以下代码按预期工作:
class Bar(val url)
class Foo(_url : String) extends Bar(_url)
{
def say() { println(url) }
}
Run Code Online (Sandbox Code Playgroud)
我同意,这既丑陋又要求麻烦.事实上,当我使用Scala类作为Hibernate实体时,我曾经遇到过这个问题 - 我在基类中使用了构造函数参数而不是字段,从而导致创建重复字段:一个在基类中,一个在派生类中.我甚至都没注意到,但是Hibernate在运行时尖叫着已经定义了重复的列映射.
所以我必须在某种程度上同意你的观点 - 这有点令人困惑,可能容易出错.这是您为" 隐含性 "和简洁代码支付的价格.
但请注意,val构造函数参数之前没有修改和修饰符不同.在没有修改不可变字段的情况下创建,同时val另外添加getter.
| 归档时间: |
|
| 查看次数: |
1718 次 |
| 最近记录: |