dopuzf0898
2019-02-20 18:14
浏览 247
已采纳

在golang中运行多个条件函数

I would like to run workflow functions using 5 functions in golang

  1. init
  2. validate
  3. process
  4. execute
  5. finalize

Each method should return the same result object and error object in case of failure

I would like to find a pattern to run this workflow rather than doing the following:

if result, err := init(); err != nil {
    if result, err := validate(); err != nil {
       if result, err := process(); err != nil {
           if result, err := execute(); err != nil {
               if result, err := finalize(); err != nil {

               }
           }
       }
    }
}

Thanks in advance Peter

图片转代码服务由CSDN问答提供 功能建议

我想使用golang中的5个函数来运行工作流程函数

    \ n
  1. init
  2. 验证
  3. 进程
  4. 执行
  5. 完成 \ n

    每个方法应该在失败的情况下返回相同的结果对象和错误对象

    我想找到一种模式来运行此工作流程 比执行以下操作:

     如果结果为err:= init();  err!= nil {
    如果结果为err:= validate();  err!= nil {
    如果结果为err:= process();  err!= nil {
    如果结果为err:= execute();  err!= nil {
    如果结果为err:= finalize();  err!= nil {
     
    } 
    } 
    } 
    } 
    } 
       
     
     

    提前感谢 Peter

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dongyan0629 2019-02-20 21:29
    已采纳

    You can create a slice of functions and make this whole process prettier, e.g.

    functions := []func() (string, error){
        function1, function2, function3, function4, function5,
    }
    for _, function := range functions {
        someValue, err := function()
        if err != nil {
            fmt.Println("Function " + someValue + " didn't feel so good.")
            break
        }
        fmt.Println("Function " + someValue + " went all right!")
    }
    

    In short, the break stops things from going on, if you wrap the above process as a function, you could also use something like

    return false
    

    in case of an error, and at the end of the total amount of iterations, say i == len(functions) -1, you could return true if everything went all right.

    It is noteworthy to mention that you can only create slice of functions that satisfies these conditions:

    • They all must have the same amount of arguments;

    • All arguments must have the same type per position;

    • They all have the same amount of return values;

    • Likewise, they (return values) must have the same type per position;

    Still, you can easily overcome these limitations by having two or three different slices. For example, function1 to function3 can all be classified as

    func () (bool, err)
    

    Where function4 and 5 are

    func () (int, err)
    

    For these functions to work you could just reiterate the first slice, then if everything goes as planned, move on to the second.

    firstSetOfFuncs := []func() (bool, error){
        function1, function2, function3,
    }
    secondSetOfFuncs := []func() (int, err){
        function4, function5,
    }
    for i, function := range firstSetOfFuncs {
        someValue, err := function()
        if err != nil {
            fmt.Println("Something went terribly wrong.")
            break
        }
        if i == len(firstSetOfFuncs) - 1 {
            for _, secondTypeOfFunc := range secondSetOfFuncs {
                someNum, anotherErr := secondTypeOfFunc()
                if anotherErr != nil {
                    fmt.Println("All seemed all right, until it didn't.")
                    break
                }
            }
        }
    }
    
    打赏 评论
  • doufen1933 2019-02-20 21:20

    As i allready said in a comment, i think the most idiomatic way would be to just call a method, check for errors. And if there was an error return it. You can of course use the simplified error handling version, like you used in your question, but even if you do that. Try to avoid that deep nesting. It's hard to read & understand (deeply) nested code.

    result,err := init()
    if err != nil {
      return nil, err // An error occured so handle it
    }
    
    result,err = validate()
    if err != nil {
      return nil, err
    }
    
    
    result,err = process()
    if err != nil {
      return nil, err
    }
    
    
    result,err = execute()
    if err != nil {
      return nil, err
    }
    
    result,err = finalize()
    if err != nil {
      return nil, err
    }
    

    Problems of your example code

    You've done the error checking wrong. You are checking for

    if err != nil

    Spoken "if there is an error". And you continue with your code, although there is an error.

    To fix that you need to write:

    var result someType
    
    if result, err := init(); err != nil {
      return nil, err // An error occured so handle it
    }
    
    if result, err := validate(); err != nil {
      return nil, err
    }
    
    
    if result, err := process(); err != nil {
      return nil, err
    }
    
    if result, err := execute(); err != nil {
      return nil, err
    }
    
    if result, err := finalize(); err != nil {
      return nil, err
    }
    
    打赏 评论

相关推荐 更多相似问题