scala – 有什么优势来确定一个特征的def的val?
在
Scala中,val可以覆盖def,但def不能覆盖val.
那么,宣布一个特征是有优势的吗?喜欢这个: trait Resource { val id: String } 而不是这个 trait Resource { def id: String } 后续的问题是:编译程序在实践中如何处理调用vals和defs,并且它实际上与val做什么样的优化?编译器坚持认为vals是稳定的 – 编译器在实践中是什么意思?假设子类实际上是使用val来实现id.在特征中指定为def的是否有惩罚? 如果我的代码本身不需要id成员的稳定性,那么在这些情况下总是使用defs,并且只有在这里确定性能瓶颈时才能切换到val,那么这可能是不可能的? 解决方法
简答:
据我所知,这些值始终通过访问器方法访问.使用def定义一个简单的方法,它返回值.使用val定义一个private [*] final字段和一个访问器方法.所以在访问方面,两者之间的差异很小.差异是概念性的,def每次都被重新评估,val只被评估一次.这显然会对性能产生影响. [*] Java私有 长答案: 我们来看下面的例子: trait ResourceDef { def id: String = "5" } trait ResourceVal { val id: String = "5" } ResourceDef& ResourceVal产生相同的代码,忽略初始化器: public interface ResourceVal extends ScalaObject { volatile void foo$ResourceVal$_setter_$id_$eq(String s); String id(); } public interface ResourceDef extends ScalaObject { String id(); } 对于生成的子类(其中包含方法的实现),ResourceDef产生的就是你所期望的,注意到该方法是静态的: public abstract class ResourceDef$class { public static String id(ResourceDef $this) { return "5"; } public static void $init$(ResourceDef resourcedef) {} } 对于val,我们简单地在包含类中调用initializer public abstract class ResourceVal$class { public static void $init$(ResourceVal $this) { $this.foo$ResourceVal$_setter_$id_$eq("5"); } } 当我们开始扩展: class ResourceDefClass extends ResourceDef { override def id: String = "6" } class ResourceValClass extends ResourceVal { override val id: String = "6" def foobar() = id } class ResourceNoneClass extends ResourceDef 我们在哪里重写,我们得到一个方法,在类中只是做你期望的. def是简单的方法: public class ResourceDefClass implements ResourceDef,ScalaObject { public String id() { return "6"; } } 而val定义了一个私有域和访问器方法: public class ResourceValClass implements ResourceVal,ScalaObject { public String id() { return id; } private final String id = "6"; public String foobar() { return id(); } } 请注意,即使foobar()也不使用字段id,而是使用访问器方法. 最后,如果我们不覆盖,那么我们得到一个在trait辅助类中调用static方法的方法: public class ResourceNoneClass implements ResourceDef,ScalaObject { public volatile String id() { return ResourceDef$class.id(this); } } 我在这些例子中删除了构造函数. 所以,始终使用访问器方法.我认为这是为了避免在扩展可以实现相同方法的多个特征时的并发症.它真的很复杂. 更长的答案: Josh Suereth在Binary Resilience at Scala Days 2012举行了一个非常有趣的演讲,介绍了这个问题的背景.这个摘要是:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- macos – 单击咆哮通知启动应用程序
- angular – tslint的含义是什么:“警告:”no-use-before-
- ISAG webservice接口发送彩信附件
- wcf学习--建立最简单的WCF服务
- WebService的基本概念:java webservice,什么是webservice
- 基于bootstrap的简单分页
- 可以使用Vagrant或Docker对Web应用程序进行质量检查吗
- adb shell时,提示error: unknown host service的解决办法
- docker – Kubernetes无法在给定的IP上看到我的应用程序
- angularjs – Angular ng – 不需要使用自定义指令