Path-dependent types are useful:
trait Sys {
type Global
}
def foo[S <: Sys](system: S)(global: system.Global) = ()
Why doesn't this work for constructors?
class Foo[S <: Sys](val system: S)(val global: system.Global)
Or am I just doing it wrong?
This seems like a bug to me. Edit : found it, this is SI-5712 .
Section §5.3 of the 2.9 SLS says:
(ps1 ) . . . (psn ) are formal value parameter clauses for the primary constructor of the class. The scope of a formal value parameter includes all subsequent parameter sections and the template t .
There is an exception:
However, a formal value parameter may not form part of the types of any of the parent classes or members of the class template t .
But it says it cannot be part of the types of any of the parent classes or members , not of any of the following parameter sections , so it does not seems to forbid path-dependent types between argument groups.
You can go around this with a secondary constructor:
class Foo[S <: Sys] private[this] () {
def this(system: S)(global: system.Global) = this
}
Edit : this secondary constructor workaround is not very good: exposing system
or global
become very difficult because only the primary constructor can declare val
s.
An example with a cast:
class Foo[S <: Sys] private[this] () {
private[this] var _system: S = _
private[this] var _global: system.Global = _
def this(system0: S)(global0: system0.Global) = {
this
_system = system0
_global = global0.asInstanceOf[system.Global]
}
lazy val global: system.Global = _global
lazy val system: S = _system
}
But this is getting awful. @senia's suggestion is much better.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.