泛型 – Scala:什么是在泛型类中进行数值运算的最佳方法?
在
Scala中,我希望能够编写使用>,/,*等运算符的泛型类,但是我没有看到如何约束T这样才能使用.
我考虑用Ordered [T]约束T,但这似乎不起作用,因为只有RichXXX(例如RichInt)扩展它,而不是Int等.我也看过Numeric [T],这只在Scala 2.8中可用吗? 这是一个具体的例子: class MaxOfList[T](list: List[T] ) { def max = { val seed: Option[T] = None list .map( t => Some(t)) // Get the max .foldLeft(seed)((i,m) => getMax(i,m) ) } private def getMax(x: Option[T],y: Option[T]) = { if ( x.isDefined && y.isDefined ) if ( x > y ) x else y else if ( x.isDefined ) x else y } } 这个类不会编译,因为有许多Ts不支持>等等 思考? 现在我使用了MixIn特性来解决这个问题: /** Defines a trait that can get the max of two generic values */ trait MaxFunction[T] { def getMax(x:T,y:T): T } /** An implementation of MaxFunction for Int */ trait IntMaxFunction extends MaxFunction[Int] { def getMax(x: Int,y: Int) = x.max(y) } /** An implementation of MaxFunction for Double */ trait DoubleMaxFunction extends MaxFunction[Double] { def getMax(x: Double,y: Double) = x.max(y) } 如果我们改变原始类,可以在实例化时混合使用. 附: Mitch,受到你重写getMax的启发,这是另一个: private def getMax(xOption: Option[T],yOption: Option[T]): Option[T] = (xOption,yOption) match { case (Some(x),Some(y)) => if ( x > y ) xOption else yOption case (Some(x),_) => xOption case _ => yOption } 解决方法
你可以使用
View Bounds.
简而言之,def foo [T<%U](t:T)是一个函数,它将采用任何或者可以隐式转换为U.因为Int可以转换为RichInt(包含你的)期望的方法),这是一个很好的使用例子. class MaxOfList[T <% Ordered[T]](list: List[T] ) { def max = { val seed: Option[T] = None list.foldLeft(seed)(getMax(_,_)) } private def getMax(xOption: Option[T],y: T) = (xOption,y) match { case (Some(x),y) if ( x > y ) => xOption case (_,y) => Some(y) } } PS – 我重写了你的getMax(…)方法来比较值而不是选项本身,并使用模式匹配而不是isDefined(…) PPS – Scala 2.8将具有可能有用的数字特征. http://article.gmane.org/gmane.comp.lang.scala/16608 附录 只是为了咯咯笑,这里的超紧凑版本完全消除了getMax方法: class MaxOfList[T <% Ordered[T]](list: List[T] ) { def max = list.foldLeft(None: Option[T]) { case (Some(x),y) if ( x > y ) => Some(x) case (_,y) => Some(y) } } 然而另一个附录 这个版本对大型列表更有效…避免为每个元素创建Some(x): class MaxOfList[T <% Ordered[T]](list: List[T] ) { def max = { if (list.isEmpty) None else Some(list.reduceLeft((a,b) => if (a > b) a else b)) } } 最后一个,我保证! 此时,您可以放弃该类并使用一个函数: def max[T <% Ordered[T]](i: Iterable[T]) = { if (i.isEmpty) None else Some(i.reduceLeft((a,b) => if (a > b) a else b)) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |