在特征和方法

时间:2015-11-20 03:48:26

标签: scala generics traits

我已在scala-user论坛中发布此问题,

https://groups.google.com/forum/#!topic/scala-user/xlr7KmlWdWI

我得到了一个我很满意的答案。但是,与此同时,我想确定这是否是唯一的结论。感谢

我的问题是,我有,

trait Combinable[A] {
  def join[B](l: List[A]): B
}

当我使用A作为字符串并将B作为Int实现此特征时,例如,

class CombineString extends Combinable[String] {
  override def join[Int](strings: List[String]) = string.size
}

显然, Int ,在join方法旁边,不是Scala整数类和 编译此代码将失败。或者,我可以改写我的特质

trait Combinable[A, B] {
  def join(l: List[A]): B
}

trait Combinable[A] {
  def join[B](l: List[A])(f: List[A] => B): B
}

我的问题是,如何实现第一个例子中定义的特征呢?如果第一个例子由于它的定义方式没有实际用途,为什么编译器不投诉?再次感谢。

2 个答案:

答案 0 :(得分:2)

您不能指望编译器能够理解哪种类型组合对您有意义,但您可以将此意义指定为多参数含义中的类型之间的关系。

结果基本上是两种被拒绝的方法的组合,但具有所需的语法。

两个被拒绝的表单中的第一个成为隐式类型:

trait Combine[A, B] {
  def apply(l: List[A]): B
}

接下来,您可以定义适当的类型组合及其含义

implicit object CombineStrings extends Combine[String, String] {
  def apply(l: List[String]) = l.mkString
}

implicit object CombineInts extends Combine[Int, Int] {
  def apply(l: List[Int]) = l.sum
}

implicit object CombinableIntAsString extends Combine[Int, String] {
  def apply(l: List[Int]) = l.mkString(",")
}

最后,我们修改隐藏f隐式结果的trait Combinable[A] { def join[B](l: List[A])(implicit combine: Combine[A, B]): B = combine(l) } 参数的第二个拒绝形式:

val a = new Combinable[String] {}
val b = new Combinable[Int] {}

现在你可以定义

a.join[String](List("a", "b", "c"))
b.join[Int](List(1, 2, 3))
b.join[String](List(1, 2, 3))

并检查

a.join[Int](List("a", "b", "c"))

运行良好

String

让编译器哭,直到你能以隐含价值的形式提供Intgit之间关系实际使用的证据

答案 1 :(得分:0)

  

我的问题是,我如何实现第一个例子中定义的特征呢?

public static class ArrayHelper
{
   public static object FindInDimensions(this object[,] target, 
   object searchTerm)
  {
    object result = null;
    var rowLowerLimit = target.GetLowerBound(0);
    var rowUpperLimit = target.GetUpperBound(0);

    var colLowerLimit = target.GetLowerBound(1);
    var colUpperLimit = target.GetUpperBound(1);

    for (int row = rowLowerLimit; row < rowUpperLimit; row++)
    {
        for (int col = colLowerLimit; col < colUpperLimit; col++)
        {
            // you could do the search here...
        }
    }

    return result;
}

编译器怎么知道那不是你想要的?