Dlaczego następujące czynności nie działają?Zrozumienie "argumentów typu nie jest zgodne z błędami parametru typu" w Scali
scala> abstract class Foo[B<:Foo[B]]
defined class Foo
scala> class Goo[B<:Foo[B]](x: B)
defined class Goo
scala> trait Hoo[B<:Foo[B]] { self: B => new Goo(self) }
<console>:9: error: inferred type arguments [Hoo[B] with B] do not conform to class Goo's type parameter bounds [B <: Foo[B]]
trait Hoo[B<:Foo[B]] { self: B => new Goo(self) }
^
scala> trait Hoo[B<:Foo[B]] extends Foo[B] { new Goo(this) }
<console>:9: error: inferred type arguments [Hoo[B]] do not conform to class Goo's type parameter bounds [B <: Foo[B]]
trait Hoo[B<:Foo[B]] extends Foo[B] { new Goo(this) }
^
Przy pierwszej próbie nie jest to Hoo[B] with B <: Foo[B]
?
Przy drugiej próbie nie jest to Hoo[B] <: Foo[B]
?
Aby zmotywować ten problem, jest biblioteka z:
// "Foo"
abstract class Record[PK, R <: Record[PK, R]] extends Equals { this: R =>
implicit def view(x: String) = new DefinitionHelper(x, this)
...
}
// "Hoo"
class DefinitionHelper[R <: Record[_, R]](name: String, record: R) {
def TEXT = ...
...
}
// now you can write:
class MyRecord extends Record[Int, MyRecord] {
val myfield = "myfield".TEXT
}
próbuję wprowadzić nową metodę rozszerzenia obok tekstowy o nazwie bytea, tak, że można napisać:
class MyRecord extends XRecord[Int, MyRecord] {
val myfield = "myfield".BYTEA // implicit active only inside this scope
}
My Próby:
class XDefinitionHelper[R <: Record[_, R]](name: String, record: R) {
def BYTEA = ...
}
trait XRecord[PK, R <: Record[PK, R]] { self: R =>
implicit def newView(x: String) = new XDefinitionHelper(x, self)
}
Ale to prowadzi do tych samych problemów, co mój mniejszy przypadek testowy powyżej.
Dzięki, teraz widzę, jak rozwiązać mój drugi próba (użycie 'extends Foo [Hoo [B]]'), ale jak naprawić jedną formę (używając self-type)? – Yang
Masz również problem z kontynuowaniem tego. Muszę zdefiniować 'class Ioo [B <: Ioo [B]] rozszerza Hoo [B] {new Goo (this)}, ale to nie działa. "Nie rozszerza także Hoo [Ioo [B]]". Ale 'class Ioo [B <: Foo [B]] rozszerza Hoo [B]' działa, nazywając 'Goo' na instancji' Ioo' od wewnątrz 'Hoo'. Jednak nie mogę tego zrobić z poziomu 'Ioo'. – Yang
Powyższe powinno być w rzeczywistości: muszę zdefiniować 'class Ioo extends Hoo [Ioo] {new Goo (this)}, ale to nie działa. Ani 'nie rozszerza Hoo [Foo [Ioo]]'. – Yang