首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala:如何通过函数对象参数实现签名不同的通用流程?

Scala:如何通过函数对象参数实现签名不同的通用流程?
EN

Stack Overflow用户
提问于 2015-02-12 07:31:55
回答 1查看 171关注 0票数 6

我是一个Java程序员,在Scala编程方面迈出了初步的步伐。

我定义了一个类似于(可能是错误的,我不知道.)的函数:

代码语言:javascript
复制
def someGenericAlgorithm(param1: String, param1: String, param3: String) = {

    val triedResult1 = someFunction(param1)
    triedResult1 match {
      case Success(result1) =>
        val triedResult2 = someOtherFunction(param2)
        triedResult2 match {
          case Success(result2) =>
            val triedPolymorphicResult = someToBeReplacedAccordingToSpecificLogicFunction(result1, result2, param3)
            triedPolymorphicResult match {
              case Success(polymorphicResult) =>
                doSomethingGeneric(polymorphicResult)                    
                ....
              case Failure(exception) =>
                ....
            }
          case Failure(exception) =>
            ....
        }
      case Failure(exception) =>
        ....
    }
  }

因此,该函数接收3个参数,按顺序处理前两个参数,获取处理结果并沿着第三个参数传递给someToBeReplacedAccordingToSpecificLogicFunction

现在我想写一个类似的函数,因为前两个函数调用是存在的,错误逻辑是相同的,唯一的区别是someToBeReplacedAccordingToSpecificLogicFunction现在是aReplacementLogicFunction

如果这两个函数具有相同的签名,我想这不会是一个问题,但是,它们没有,aReplacementLogicFunction有不同的参数,更具体地说,还有两个参数。那么,您可能会说,我可以传递Option参数,在第一种情况下,这两个Options是Nones,这样我就可以将我的两个函数对齐,使其具有相同的签名,因此:

代码语言:javascript
复制
def someToBeReplacedAccordingToSpecificLogicFunction(result1: Int, result2: Int, param3: String, unused1:Option[String] = None, unused2:Option[String] = None)

def aReplacementLogicFunction(result1: Int, result2: Int, param3: String, used1:Option[String], used2:Option[String])

但是,第三个流存在于第一个函数不存在的参数是另一种类型的情况下,比如MyClass:

代码语言:javascript
复制
def anotherReplacementLogicFunction(result1: Int, result2: Int, param3: String, used1: MyClass, used2: MyClass)

问题是,我将如何将这些函数推广到某个重构的泛型算法函数,该函数将作为参数接收一个函数。是否有一种方法可以定义如下:

代码语言:javascript
复制
def refactoredOutCoreLogic(param1: String, param1: String, param3: String, polimorphicFunction: SignatureUnknown)

Java回答我自己的问题

在Java中解决这个问题的方法是定义一个类层次结构,类似于:

代码语言:javascript
复制
abstract class ResultKeeperRunnable implements Runnable {
    protected int param1, param2;
    void setParam1(...) {...}
    void setParam2(...) {...}
}

class SomeToBeReplacedAccordingToSpecificLogicFunctionClass extends ResultKeeperRunnable  {
    String param3;
    // ctor receiving all params omitted for brevity 
    void run() {
      // do specific Logic
    }
}

class AReplacementLogicFunctionClass extends ResultKeeperRunnable {
    String param3, param4, param5;
    // ctor receiving all params omitted for brevity 
    void run() {
      // do specific Logic
    }
}

class AnotherReplacementLogicFunctionClass extends ResultKeeperRunnable {
    String param3;
    MyClass param4, param5;
    // ctor receiving all params omitted for brevity 
    void run() {
      // do specific Logic
    }
}

最后,剔除核心逻辑的方法应该是这样的:

代码语言:javascript
复制
void refactoredOutCoreLogic(String param1, String param2, String param3, ResultKeeperRunnable polimorphicLogic) {
    // error handling logic removed for brevity
    int result1 = someMethod(param1);
    int result2 = someOtherMethod(param2);
    polymorphicLogic.setParam1(result1);
    polymorphicLogic.setParam2(result2);
    polymorphicLogic.run()
    ...

}

Scala解决方案是否不再是上述Java解决方案在语法上不同的克隆?似乎应该有一个更优雅的解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-12 15:22:19

您有一个接受result1result2和一系列其他参数的函数。

您需要一个只接受result1result2的函数。

要做到这一点,请使用部分适用。编写您的可替换函数,在后面加上第二组括号,以像这样仓促地执行,以保存公共参数:

代码语言:javascript
复制
def aReplacementLogicFunction(param3: String, used1:Option[String], used2:Option[String])(result1: Int, result2: Int)

然后将部分应用的函数传递到您的公共函数中,如下所示:

代码语言:javascript
复制
someGenericAlgorithm(param1, param2, aReplacementLogicFunction(param3, used1, used2))

对于一般的算法来说,它完全不知道额外的参数。这些都是在调用函数之前应用的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28471724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档