作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
trait Thing {
type Out
def get: Out
}
case class Wrapper(t: Thing) extends Thing {
type Out = t.Out
override def get = t.get
}
def hey(t: Thing): t.Out = Wrapper(t).get
这给了我一个类型错误,尽管它显然是类型安全的。我想知道如何正确地向编译器证明这是安全的,而无需进行强制转换。
有什么想法吗?
最佳答案
如果你真的、真的不想在 Wrapper
上放置类型参数,你可以用一个不那么健忘的方式来推出你自己的假案例类apply
:
trait Thing {
type Out
def get: Out
}
abstract class Wrapper(t: Thing) extends Thing
object Wrapper {
def apply(t: Thing): Wrapper { type Out = t.Out } =
new Wrapper(t) {
type Out = t.Out
def get: Out = t.get
}
}
def hey(t0: Thing): t0.Out = Wrapper(t0: Thing { type Out = t0.Out }).get
(在现实生活中,您还需要定义案例类为您提供的所有其他内容 - 有用的相等性等)
问题是Wrapper.apply
当您定义案例类时自动生成的仅返回 Wrapper
,这意味着编译器丢失了有关其 Out
的所有静态信息。 。如果你自己写apply
,您可以通过将返回类型设置为指定 Out
的细化类型来保留该信息。 .
为了证明它有效:
scala> val myThing = new Thing {
| type Out = String
| def get = "foo"
| }
myThing: Thing{type Out = String} = $anon$1@5e265ba4
scala> hey(myThing)
res0: myThing.Out = foo
scala> val foo: String = hey(myThing)
foo: String = foo
因此编译器能够跟踪 Out
的事实是 String
一路走来。
关于scala - 如何正确地通过包装类来线程化类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33570557/
我是一名优秀的程序员,十分优秀!