谜题——用自定义类型暴露私有成员的公共子成员
Posted
技术标签:
【中文标题】谜题——用自定义类型暴露私有成员的公共子成员【英文标题】:Puzzle -- exposing a public sub-member of private member with custom type 【发布时间】:2012-01-31 12:00:13 【问题描述】:我想做这样的事情(示例被简化,但包含所有关键部分):
class Master
type DataType = Int
var counter : DataType = 0
class Slave(private val master : Master)
val counter = master.counter // (*)
这里 (*) 我得到错误:
私有值 master 将其定义范围作为类型的一部分进行了转义 从属.this.master.DataType
val counter = master.counter
我理解错误,但我不明白原因 - 类型是类 Master
的一部分,而不是对象 master
,所以如果类是私有的,而不是对象,这一点很重要。好吧,至少在理论上是这样。
快速解决方法很容易:
val counter : Master#DataType = master.counter
但我相信这是与以前完全相同的代码的显式版本,它“只是”需要更多的输入。那么这是一个功能吗?
问题:
一个类型(这里是 DataType)可以依赖于对象,而不是 Scala 中的类(即类的每个实例的类型定义)吗?
【问题讨论】:
【参考方案1】:你想错了
这是与之前完全相同的代码的显式版本
Master#DataType
和 master.DataType
是两种不同的类型。
master.DataType
是那些以master
作为外部对象的DataType
实例的类型。换句话说,正是你问的,但显然master
是类型的一部分,如果master
不是,则类型不能暴露。
Master#DataType
是任何外部对象的任何DataType
实例的类型(相当于Java 中的Master.DataType
)。
回复评论:
类型成员可以在子类(包括只包含一个对象的匿名子类)中被覆盖,但只能被兼容类型覆盖。在您的示例中,DataType
在Master
中已经是具体的,因此唯一与它兼容的类就是它自己。所以像
val a = new Master
override type DataType = String
不会进行类型检查,这是有道理的:你会得到var counter: String = 0
,这是无稽之谈。但是
val a = new Master
override type DataType = Int
会起作用(但不太有用)。
所以只有重写 abstract 类型的成员才有意义。但是它们以与内部类相同的方式进行类型检查,因此a.DataType
通常被认为与b.DataType
不同——即使它们实际上不能不同!
【讨论】:
谢谢,所以如果我理解正确(但是我相信我没有在“Scala 编程”中读到它——或者它可能滑倒了),你可以为类的每个实例定义类型,不仅是每个班级。 感谢您的更新,这非常有价值,不幸的是,我无法为您的帖子投票超过 1 次 :-) 这是 Scala 中有用的东西之一,当来自其他 OOP 语言时可能会成为“陷阱”。非常简洁的回答;值得我点赞;)。以上是关于谜题——用自定义类型暴露私有成员的公共子成员的主要内容,如果未能解决你的问题,请参考以下文章