Scala更改trait中定义的函数的参数
因为我在任何地方都没有找到解决问题的方法,所以我想我可能是在想一个非常错误的方向 我的问题是: 我有一个特征a和另一个特征B,以及伴随对象AB1、AB2、AB3等等。单例对象扩展trait A,类扩展trait B。这些类的许多对象都在一个列表中 在这些对象上,我想使用在相应的singleton对象中定义的函数,这些函数接受与singleton对象相同类的对象 这是特征的一个例子:Scala更改trait中定义的函数的参数,scala,functional-programming,traits,companion-object,Scala,Functional Programming,Traits,Companion Object,因为我在任何地方都没有找到解决问题的方法,所以我想我可能是在想一个非常错误的方向 我的问题是: 我有一个特征a和另一个特征B,以及伴随对象AB1、AB2、AB3等等。单例对象扩展trait A,类扩展trait B。这些类的许多对象都在一个列表中 在这些对象上,我想使用在相应的singleton对象中定义的函数,这些函数接受与singleton对象相同类的对象 这是特征的一个例子: trait A { def compare(firstB: B, secondB: B) : Int }
trait A {
def compare(firstB: B, secondB: B) : Int
}
trait B {}
和伴生物体:
class AB1(val variable: Int) extends B {}
object AB1 extends A {
def apply(list: List[Int]): Option[AB1] = {
if(list.foldLeft(0)(_ + _) < 10 && list.nonEmpty)
some(new AB1(list.head))
else
null
}
override def compare(ab11: AB1, ab12: AB1): Int = {
if(ab11 > ab12)
1
else if(ab11 > ab12)
-1
else
0
}
}
在路上我遇到了两个问题:
b.getClass
不等于AB1.getClass
当b是类AB1的对象时。但这不是我的主要问题。我发现了一个使用字符串比较的解决方案,这真的很不漂亮,但现在,它可以工作了compare
函数,因为否则它不能在扩展trait A的任何单例对象上强制转换。但是我发现没有办法用变量类型的参数定义函数列表[List[C]
。那些C
的列表可能能够用它创建一个AB1对象,但可能是AB2,也可能是AB3等等。所以我有
val c: List[C] = (C1, C2, C4)
val aList: List[A] = (AB1, AB2, AB3, ...)
val bestB: B = (for{
element <- aList
} yield element (c)).flatten.head // Because the List aList is ordered: AB1 is the best case, AB2 the second best and so on.
valc:List[c]=(C1、C2、C4)
值列表:列表[A]=(AB1,AB2,AB3,…)
val bestB:B=(对于{
元素我认为您需要使用隐式比较器
:
trait B
case class AB1(variable: Int) extends B
case class AB2(variable1: Int, variable2: Int) extends B
implicit object AB1Comparator extends Comparator[AB1] {
override def compare(o1: AB1, o2: AB1): Int = java.lang.Integer.compare(o1.variable, o2.variable)
}
implicit object AB2Comparator extends Comparator[AB2] {
override def compare(o1: AB2, o2: AB2): Int = java.lang.Integer.compare(o1.variable1, o2.variable1) match {
case 0 => java.lang.Integer.compare(o1.variable2, o2.variable2)
case other => other
}
}
def compare[A](obj1: A, obj2: A)(implicit comparator: Comparator[A]) = {
comparator.compare(obj1, obj2)
}
val ab1List = List(AB1(1), AB1(2), AB1(3))
val ab1Compare = compare(ab1List.head, ab1List.tail.head)
val ab2List = List(AB2(1, 1), AB2(1, 1), AB2(1, 3))
val ab2Compare = compare(ab2List.head, ab2List.tail.head)
或者,如果要对列表进行排序,则应使用排序
:
trait B
case class AB1(variable: Int) extends B
implicit object AB1Ordering extends Ordering[AB1] {
override def compare(o1: AB1, o2: AB1): Int = java.lang.Integer.compare(o1.variable, o2.variable)
}
val ab1List = List(AB1(1), AB1(2), AB1(3))
val ab1ListSorted = ab1List.sorted
老实说,我仍然不明白你的根本问题是什么。但我会尽力回答我所理解的
首先,如果您想在从trait重写函数时更改参数的类型。然后,答案是您不能!-因为这会破坏规则
但是你可以用一个简单的方法实现你想要的
现在,假设b11和b12是B1的实例,您只需编写
implicitly[BComparator[B1]].compare(b11, b12)
您好@SimonDose,这里有很多东西……首先,您不应该使用null,尤其是在您已经使用Option的情况下。其次,AB1.getClass
与b.getClass
不同,因为AB1作为一个对象有它自己的类(即使它是一个伴生对象)第三,你不应该检查类实例,而应该使用模式匹配,这在Scala中更为惯用。最后,你能把你的问题说得更清楚一点吗?我已经读了三遍了,但不能确切地理解你的问题是什么。是的,这有点让人困惑。感觉这与有序特征有关,但不清楚是什么t你的目标是。为什么要使用对象
而不是案例类
?@Luis Miguel Mejía Suárez感谢你的回答。我编辑了这个问题,让它更清楚我的问题到底是什么。我知道AB1和b是不同的类。但是我如何使用模式匹配来比较它们呢?@Andy Hayden,因为静态f我使用的函数和变量,我认为对象是正确的choice@SimonDose在case类+companion对象中,你不能两者兼得吗?
trait B
case class AB1(variable: Int) extends B
implicit object AB1Ordering extends Ordering[AB1] {
override def compare(o1: AB1, o2: AB1): Int = java.lang.Integer.compare(o1.variable, o2.variable)
}
val ab1List = List(AB1(1), AB1(2), AB1(3))
val ab1ListSorted = ab1List.sorted
trait B {}
trait BComparator[Bi <: B] {
def compare(firstB: Bi, secondB: Bi): Int
}
class B1 extends B {}
object B1 {
implicit val B1Comparator: BComparator[B1] = new BComparator[B1] {
override def compare(firstB: B1, secondB: B2): Int = ???
}
}
implicitly[BComparator[B1]].compare(b11, b12)