【问题标题】:Convert string into operator in Scala在Scala中将字符串转换为运算符
【发布时间】:2016-03-26 02:22:10
【问题描述】:

如何将 Scala 中的字符串转换为相应的运算符? 给定两个整数和字符串“+”,我想要这两个整数相加的结果。

【问题讨论】:

    标签: string scala operators eval evaluate


    【解决方案1】:

    最后一个问题很简单:

    def applyOperator(x: Int, y: Int, operator: String) = operator match {
      case "+" => x + y
      case "-" => x - y
      ...
    }
    

    可以尝试使用 Twitter 的 Eval 库或反射,但考虑到更简单的解决方案,我不推荐它。

    对于第一个问题:运算符本身不是值,因此您不能“将字符串转换为运算符”。但是您可以接近:将字符串转换为将添加(或减去等)其参数的函数:

    def stringToOperator(operator: String): (Int, Int) => Int = operator match {
      case "+" => _ + _
      case "-" => _ - _
      ...
    }
    

    您甚至可以将其概括为不仅仅适用于整数:

    def stringToOperator[A: Numeric](operator: String): (A, A) => A = operator match { ... }
    

    (这显然也适用于第一个答案。)

    【讨论】:

    • 请您为第一个代码添加一些解释。孤独的代码什么也没说。
    • 我已经扩展了一些答案。
    【解决方案2】:

    这个

    case class Evaluatee(v1: Int, operator: String, v2: Int)
    
    object Evaluator {
      def raw(s: String)(v1: Int, v2: Int) = s match {
          case "+" => (v1 + v2)
          case "-" => (v1 - v2)
          case "*" => (v1 * v2)
          case "/" => (v1 / v2)
      }
    
      def evaluate(evaluatee: Evaluatee) =
        raw(evaluatee.operator)(evaluatee.v1, evaluatee.v2)
    }
    

    完成了这个测试:

      test("1+1=2"){
        assert(Evaluator.evaluate(Evaluatee(1, "+", 1)) == 2)
      }
      test("2-1=1"){
        assert(Evaluator.evaluate(Evaluatee(2, "-", 1)) == 1)
      }
      test("1+1=2 raw"){
        assert(Evaluator.raw("+")(1,1) == 2)
      }
    

    【讨论】:

      【解决方案3】:

      我们不能只做类似1 "+" 2 的事情,因为我认为 scala 的最大特点是可以创建自己的DSLapply 方法,但我不能一无所有地调用它,我很确定我们总是需要使用(){} 例如List(1) 我们不能使用List 1 但我们可以使用List{1}

      但试试这个也许对你有用

      case class NumOp (num1:Int){
              def apply(op:String)(num2:Int):Int = {
                              op match {
                                      case "+" => num1+num2
                                      case "-" => num1-num2
                                      case _ => 0
                              }
              }
      }
      
      object ConvertsNumOp{
              implicit def convert(a:Int):NumOp= NumOp(a)
      }
      
      
      import ConvertsNumOp._
      
      scala> 2 ("-") (1)
      res0: Int = 1
      
      scala> 4 ("-") (2)
      res1: Int = 2
      
      scala> 4 ("+") (2)
      res2: Int = 6
      scala> 4 ("-") (2) ("+") (1) ("-") (8)
      res0: Int = -5
      

      你可以动态地做事,所以也许可以工作。

      已编辑:

      这是另一个版本的NumOp 可能是最干净的

      case class NumOp(num1:Int) {
              def apply(op:String):Int => Int = {
                              op match {
                                      case "+" => num1.+_
                                      case "-" => num1.-_
                                      case _ =>  throw new NotImplementedError("Operator not implemented")
                              }
              }
      }
      

      动态使用

      val numList = List(1,2,3,4,5,6,7,8,9,10);
      val optList = List("+","-");
      var retVal = for{ a <- numList; op <- optList } 
                            yield (a)(op)(a)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-14
        • 2019-03-24
        • 2011-07-04
        • 2011-10-28
        • 1970-01-01
        • 2014-09-03
        相关资源
        最近更新 更多