Scala类型:A类不等于T所在的T:类型T = A.
我正在阅读“
Scala编程”一书的第20.7节,我想知道为什么这段代码编译时:
class Food class Fish extends Food class Grass extends Food abstract class Animal { type SuitableFood <: Food def eat(food: SuitableFood) } class Cow extends Animal { type SuitableFood = Grass override def eat(food: Grass) {} } val bessy: Animal = new Cow bessy eat (new bessy.SuitableFood) 此代码没有(其余代码与之前相同,只有最后一行更改): bessy eat (new Grass) 据我所知,Grass的类型与Cow.SuitableFood相同. 另外,我对此示例有另一个问题: 如果bessy是Animal类型,编译器怎么知道它需要一个类型SuitableFood – >草而不是一种食物? ‘因为尝试提供一个新的食物给我一个类型不匹配的编译错误,但类动物需要一个类型食物和bessy的类型明确定义:动物 解决方法
这是因为bessie被宣布为动物而不是牛. bessie.SuitableFood是一种“路径依赖型”(见下文).
试试这个: val clarabelle: Cow = new Cow clarabelle eat (new Grass) 这是有效的,因为编译器可以从clarabelle的声明类型中推断出clarabelle.SuitableFood = Grass. 由于bessie被宣布为Animal,而不是Cow,编译器无法安全地推断出那个bessie.SuitableFood = Grass.*当你说新的bessie.SuitableFood时,编译器生成代码来查看实际的bessie对象并生成一个新的实例适当的类型. bessie.SuitableFood是一种“路径依赖型”:导致最后一个标识符(SuitableFood)的“path”(bessie.部分)实际上是该类型的一部分.这使您可以为同一个类的每个单独对象提供类型的自定义版本. *嗯,实际上,我认为如果编译器更聪明一点,它可以推断出bessie.SuitableFood = Grass,因为bessie是val,而不是var,因此不会改变它的类型.换句话说,编译器应该知道即使bessie被宣布为Animal,她也真的是牛.也许编译器的未来版本将利用这些知识,也许有一个很好的理由为什么这不是一个好主意,哪个人比我更专业的人会告诉我们. (后记:一个刚做过!见下面Travis Brown的评论.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- unix – 为什么JDK与Web / Application Server一起安装?
- 关于Scala泛型:找不到元素类型T的类清单
- 详解AngularJs过滤器--filter
- Vim 简易配置
- twitter-bootstrap – Bootstrap:窗口的表格太宽
- scala – 为什么在getOrElse中返回会导致尾递归不可能?
- 如何在angular cli项目中包含node_modules中的资源
- WebService 应用场景
- amazon-web-services – 如何配置在AWS/ElasticBeanstalk/
- 服务使用CXF框架客户端使用Axis2框架的webservice实现方案