次のようなことをしたいユースケースがあります
trait Foo {
def bar[T](x: T)(implicit ev: x.type =:= this.type) = {}
}
そのため、パラメーター x がメソッドが呼び出されるクラスと同じ型を持つ場合にのみ、bar の呼び出しがコンパイルされます。
各インスタンスには異なる this.type があるため、この場合 this.type が役に立たないことは明らかです。これは目標を示すだけです。
完全な問題は次のようになります。
trait Foo {
def bar[B <: Foo](o: B) = {} // with some check added
}
abstract class Abstract extends Foo
class Concrete1 extends Abstract
class Concrete2 extends Abstract
case class Wrapped(a: Abstract)
val c1a = new Concrete1
val c1b = new Concrete1
val c2 = new Concrete2
val ts1 = new Wrapped(new Concrete1)
c1a.bar(c1b) // should compile
ts1.a.bar(c1b) // should also compile
c2.bar(c1b) // should not compile
抽象型を使用して、c1a.bar(c1b) をコンパイルし、意図したように c2.bar(c1b) をコンパイルせず、ts1.a.bar(c1b) もコンパイルしないソリューションを見つけました。この投稿の update2 で説明されているアプローチのような他のアイデアも確認しましたが、ここでは Self の共分散によりバーを定義できません。
私が見ていない解決策はありますか?Abstract をジェネリック型にしない限り (これは避けたい)。
ありがとう