Scala 如何检查方法参数的类型是否与此方法相同?

Scala 如何检查方法参数的类型是否与此方法相同?,scala,Scala,我有一个用例,我想做一些 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 som

我有一个用例,我想做一些

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
trait Foo[T]{
  def bar(t:T) = {}
}
trait Foo { self:StrictSelf[_] =>
  def bar[T <: Self](o: T) = {}
}

abstract class Abstract extends Foo { self:StrictSelf[_] => }

class Concrete1 extends Abstract with StrictSelf[Concrete1] {
  type Self = Concrete1
}

class Concrete2 extends Abstract with StrictSelf[Concrete2] {
  type Self = Concrete2
}

case class Wrapped[T <: Abstract with StrictSelf[T]](a: T)
trait Foo{

def bar[B您可以这样参数化您的特征:

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
trait Foo[T]{
  def bar(t:T) = {}
}
trait Foo { self:StrictSelf[_] =>
  def bar[T <: Self](o: T) = {}
}

abstract class Abstract extends Foo { self:StrictSelf[_] => }

class Concrete1 extends Abstract with StrictSelf[Concrete1] {
  type Self = Concrete1
}

class Concrete2 extends Abstract with StrictSelf[Concrete2] {
  type Self = Concrete2
}

case class Wrapped[T <: Abstract with StrictSelf[T]](a: T)
然后扩展trait的类在扩展时会给出自己的类型:

abstract class Abstract[T] extends Foo[T]

class Concrete1 extends Abstract[Concrete1]
class Concrete2 extends Abstract[Concrete2]
case class Wrapped[T](a:Abstract[T])

这将解决您的问题,代价是必须在从
Foo

扩展的每个类上定义类型。这样做的唯一方法(不引入类型参数)是引入
抽象类型
Foo
需要知道它的
bar
方法中的类型:

trait Foo {
  type Self
  def bar[T <: Self](o: T) = {} // with some check added
}

abstract class Abstract extends Foo {
  type Self = Abstract
}

class Concrete1 extends Abstract {
  type Self = Concrete1
}

class Concrete2 extends Abstract {
  type Self = Concrete2
}
完整的代码如下所示:

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
trait Foo[T]{
  def bar(t:T) = {}
}
trait Foo { self:StrictSelf[_] =>
  def bar[T <: Self](o: T) = {}
}

abstract class Abstract extends Foo { self:StrictSelf[_] => }

class Concrete1 extends Abstract with StrictSelf[Concrete1] {
  type Self = Concrete1
}

class Concrete2 extends Abstract with StrictSelf[Concrete2] {
  type Self = Concrete2
}

case class Wrapped[T <: Abstract with StrictSelf[T]](a: T)
trait Foo{self:StrictSelf[\u]=>
定义条[T}
类Concrete1使用StrictSelf[Concrete1]扩展抽象{
类型Self=1
}
类Concrete2使用StrictSelf[Concrete2]扩展抽象{
类型Self=2
}
案例类包装[T:T]
}
trait Foo{self:SelfType[\u]=>
定义条(o:Self)={}
}
抽象类抽象扩展Foo{self:SelfType[\u]=>}
类Concrete1使用SelfType[Concrete1]扩展抽象
类Concrete2使用SelfType[Concrete2]扩展抽象

案例类包装的[TEECOLORs ANSWERS非常有效,并且比我同时发现的替代解决方案更接近问题。但是这个替代解决方案非常适合我的用例,因此可能对以后在这个问题上遇到困难的其他人也很感兴趣

我将工具栏移动到一个新对象:

object Bar {
  def bar[A <: Foo, B <: Foo](a: A, b: B)(implicit ev: A =:= B) = {}
}
对象栏{

def棒[A在您的示例中,
ts1
的类型是
Wrapped
,与
Abstract
无关。它只是碰巧有一个类型为
Abstract
的字段,但它无论如何都不是其层次结构的一部分,它甚至没有
bar
方法。是的,对不起,这是一个错误。当然,我指的是ts1.A.bar,而不是ts1.bar.Yep、 这是真的,但我想避免这个解决方案(我试图在最后用“不使抽象成为泛型类型”部分来表示).正如已经看到的,这还需要一个更改的包装器,它在示例中只是具有类型为Abstract的成员的类的占位符。这只是它如何扩展到代码中的开始。