【问题标题】:Having parameter syntactic sugar in scala在scala中有参数语法糖
【发布时间】:2014-08-10 23:08:56
【问题描述】:

对于依赖于对象的操作,我有一点语法糖:

case class EllipticOperand (p : Point)
{
  def + (q : => Point) = curve.sum(p,q)
  def * (n : => BigInt) = curve.times(p,n)
}
implicit def PointToOperand(p : Point) = EllipticOperand(p)

case class EllipticMultiplier (n : BigInt)
{
def * (p : => Point) = curve.times(p,n)
}
implicit def BigIntToOperand (n : BigInt) = EllipticMultiplier(n)

我想封装一些class SyntacticSugar[Point](curve : main.Curve[Point]) 以便在其他类定义中使用它,而不必复制/粘贴它。

我尝试过这样使用它:

val sugar = new util.SyntacticSugar(curve)
import sugar._

但是,这不起作用,我不能在之后使用+*

【问题讨论】:

  • 为什么不把你混入其他职业的特质呢?
  • 问题是,traits 不支持参数,而且我的语法糖每次都依赖于特定的曲线。顺便谢谢。
  • 您这样定义了SyntacticSugar 类:class SyntacticSugar[Point](curve : main.Curve[Point])?那么上面de code sn-p中的Point不是类而是类型参数?
  • 嗯,Point 确实是一个类型参数,但curve 是一个对象。

标签: scala parameters syntactic-sugar


【解决方案1】:

如果我按照你建议的方式实施它就可以了......

case class Point(x: Int, y: Int)

trait Curve[T] {
  def sum(p: T, q: T): T
  def times(p: T, n: Int): T
}

// dummy implementation
class PointCurve extends Curve[Point] {
  override def sum(p: Point, q: Point) = Point(p.x+q.x, p.y+q.y)
  override def times(p: Point, n: Int) = Point(p.x*n, p.y*n)
}


object util {
  class SyntacticSugar[T](curve: Curve[T]){
    case class EllipticOperand(p: T){
      def +(q: =>T) = curve.sum(p, q)
      def *(n: =>Int) = curve.times(p,n)
    }
    implicit def point2Operand(p: T) = EllipticOperand(p)
  }
}

现在您可以在Point 上使用+* 作为运算符:

scala> val sugar = new util.SyntacticSugar(new PointCurve)
sugar: util.SyntacticSugar[Point] = util$SyntacticSugar@4ed4b486

scala> import sugar._
import sugar._

scala> Point(1,2) + Point(2,3)
res0: Point = Point(3,5)

scala> Point(1,2) * 3
res1: Point = Point(3,6)

【讨论】:

  • 它对我不起作用,是因为它在不同的文件中吗?如果是这样,这是一个问题,因为我不会将所有课程放在同一个课程中。
  • 不必将所有类都放在同一个文件中。只有SyntacticSugarEllipticOperandpoint2Operand 方法必须在同一个文件中,因为SyntacticSugar 是另外两个的封闭类。你会得到什么样的错误?在哪几行代码?
  • 我得到overloaded method value * with alternatives (...) cannot be applied to (Point) a * p 其中aBigIntp 一个点。 (我在第一条消息中添加了BigInt 的语法糖)。
  • 我认为你正在做5 * Point(1,2),但要让它工作你应该做BigInt(5) * Point(1,2)真的 奇怪的是,这仍然不起作用...implicitly[BigInt=>{def *(p: =>Point): Point }] 找到了适当的隐式视图,但编译器在必要时不会应用它。我认为你应该为这个问题打开一个单独的问题,因为这很奇怪。
  • 看来,如果您将按名称参数更改为按值参数(删除 =>),则隐式转换确实有效。仍然没有真正解释为什么它适用于带有名称参数的Point * BigInt,但不适用于BigInt * Point...看起来类型参数和名称参数的组合使编译器感到困惑...
猜你喜欢
  • 2013-07-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多