当前位置: 首页 > 知识库问答 >
问题:

具有特征匹配的Scala泛型

巫马阳飙
2023-03-14

看看这个代码。

trait SomeMix {

}

trait Processor[T] {

  def processMix(t: T with SomeMix) = {
    println("processing T with Mix")
  }

  def processAsUsual(t:T)= {
    println("processing T")
  }

  def process(t:T) = {
    t match {
      case mix: SomeMix => processMix(mix) // <---- error here 
      case _ => processAsUsual(t)
    }
  }
}

愚蠢的Scala编译器在这里显示错误:

错误:(22, 39) 类型不匹配;找到: mix.type (底层类型 SomeMix) 必需: T with SomeMix 大小写混合: SomeMix =

它不理解表达式I匹配到在某种混合已经是类型T。好吧,让我们帮助他。更改代码:

   def process(t:T) = {
    t match {
      case mix: T with SomeMix => processMix(mix) // <---- warning here 
      case _ => processAsUsual(t)
    }
  }

现在,它同意一切都是正确的,但显示警告:

警告:(22,17)抽象类型模式T未选中,因为它已通过擦除大小写混合消除:T与SomeMix=

有什么好的方法可以避免错误和警告吗?

共有3个答案

公德明
2023-03-14

这样地?

trait SomeMix {

}

trait Processor[T] {

  def processMix(t: SomeMix) = {
    println("processing SomeMix")
  }

  def processAsUsual(t:T)= {
    println("processing T")
  }

  def process(t:T) = {
    t match {
      case mix: SomeMix => processMix(mix)
      case _ => processAsUsual(t)
    }
  }
}
林烨华
2023-03-14

因为,正如您所提到的,它肯定是<code>T</code>的一个实例,所以您可以取消选中警告:

case mix: (T @unchecked) with SomeMix

注意,它仍然是未检查的,在运行时只测试匹配者是< code>SomeMix的实例;如果你换成例如

def process(t: Any) = ...

你会得到不好的结果。

欧阳狐若
2023-03-14

Scala编译器并不愚蠢。由于类型擦除,无法使用SomeMix检查t是否为<code>t的实例。尝试将TypeClass与静态调度一起使用,而不是动态类型调度。

例如

trait SomeMix {
  def someMethod: String = "test2"
}

class SomeType

def process[T](t: T)(implicit P: Process[T]): Unit = P.process(t)

trait Process[T] {
  def process(t: T): Unit
}

implicit val processString: Process[SomeType] = s =>
  println(s"processing $s as usual")
implicit val processStringWithSomeMix: Process[SomeType with SomeMix] = s =>
  println(s"processing $s with mix ${s.someMethod}")

process(new SomeType)
process(new SomeType with SomeMix)
 类似资料:
  • 目标 在这一章中, 我们将看到如何将一个图片上的特征和其他图片上的特征匹配起来。 我们将使用 OpenCV 中的蛮力匹配器和 FLANN 匹配器。 蛮力匹配器基础 蛮力匹配器很简单。 它采用第一组中的一个特征的描述符并且使用一些距离计算与第二组中的所有其他特征匹配。 返回最接近的一个。 对于BF匹配器,首先我们必须使用 cv2.BFMatcher() 来创建 BFMatcher 对象。 它需要两个

  • 目标 在本章中, 我们将看到如何将一个图像中的特征与其他图像进行匹配。 我们将在OpenCV中使用Brute-Force匹配器和FLANN匹配器 Brute-Force匹配器的基础 蛮力匹配器很简单。它使用第一组中一个特征的描述符,并使用一些距离计算将其与第二组中的所有其他特征匹配。并返回最接近的一个。 对于BF匹配器,首先我们必须使用cv.BFMatcher()创建BFMatcher对象。 它需

  • 我定义了一个通用的环境特征: 为此,我提供了以下实现: 此外,我定义了一个通用事件特征,该特征具有一个接受通用环境作为参数的方法: 对于这个事件特征,我提供了以下实现,其中exec()方法接受MyEnvironment类型的参数,使我能够访问MyEnvironment的特定值。 然而,Scala编译器输出了一个错误,从中可以看出MyEnvironment似乎没有被识别为环境[整数]: 错误:方法e

  • 问题内容: Mockito提供: 如何避免警告,如果需要呢? 问题答案: 对于Java 8及更高版本,很简单: 对于Java 7及更低版本,编译器需要一些帮助。用途:

  • 主要内容:实例,实例,特征构造顺序Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。 与接口不同的是,它还可以定义属性和方法的实现。 一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。 Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示: 实例 trait Equal {   def isEq

  • Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。 与接口不同的是,它还可以定义属性和方法的实现。 一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。 Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示: trait Equal { def isEqua