【问题标题】:How to make this code more functional如何让这段代码更实用
【发布时间】:2012-12-23 08:03:41
【问题描述】:

我是 Scala 和函数式编程的新手。我正在尝试通常的初学者应用程序和脚本(显然使用了一些过度技术)

不管怎样,我有一个计算器的代码,它接受参数和一个开关来指示要在参数上使用的操作。

object Main {
    def main(args: Array[String]): Unit = {

        var calc = calculate( "" , _:List[Int])
        var values:List[Int] = List()

        if(args.size < 1) println("No arguments supplied") else{
            args collect {_ match{
                    case arg if arg.contains("-") => {
                            if(values.size>0){
                                calc(values)
                                values = List()}
                            calc = calculate( arg , _:List[Int])
                        }
                    case arg => {
                            try{
                                val value=arg.toInt
                                values = values ::: List(value)
                            }catch{case e:NumberFormatException=>println("\nError:Invalid argument:\""+arg+"\"\nCannot convert to Integer.\n")}
                    }
                }
            }
            calc(values)
        }
    }

    def sum(values:List[Int]) { println("The sum is:"+(values.foldLeft(0)((sum,value) => sum + value))) }

    def subtract(values:List[Int]) {
        val initial:Int = values(0)

        var total:Int = 0
        for(i <- 1 until values.size){
            total = total + values(i)
        }
        val diff:Int = initial - total
        println("The difference is:"+diff)
    }

    def calculate(operation:String,values:List[Int]) = operation match {
        case "-sum" => sum(values)
        case "-diff" => subtract(values)
        case _ => println("Default operation \"Sum\" will be applied");sum(values)
    }
}

如果有更好的方法,id 喜欢查找的一些点就像删除 try catch 语句。

非常欢迎编写此应用程序的更好方法。

【问题讨论】:

    标签: scala functional-programming refactoring


    【解决方案1】:

    这个怎么样?

    object Main extends App {
        require(args.size > 0, "Please, supply more arguments")
    
        @annotation.tailrec
        def parseArguments(arguments: List[String], operation: String, values: List[Int]() = Nil) {
            if(values.nonEmpty) calculate(operation, values)
            arguments match {
                case op::unprocessed if op.startsWith("-") => parseArguments(unprocessed, op)
                case maybeNumber::unprocessed => {
                    val newValues = try {
                        maybeNumber.toInt::values
                    } catch {
                        case _: NumberFormatException => 
                            println("\nError:Invalid argument:\""+maybeNumber+"\"\nCannot convert to Integer.\n")
                            values
                    }             
                    parseArguments(unprocessed, operation, newValues)   
                }
                case Nil => //done processing, exiting
            }
        }
    
        parseArguments(args.toList, "")
    
        def diff(values:List[Int]) = {
            val initial::tail = values
            val total = tail.sum
            initial - total
        }
    
        def calculate(operation:String, values:List[Int]) = operation match {
            case "-sum"  => println("The sum is " + values.sum)
            case "-diff" => println("The difference is: " + diff(values))
            case _       => 
                            println("""Default operation "Sum" will be applied""")
                            sum(values)
        }
    }
    

    【讨论】:

    • 相当优雅的做事方式!由于没有添加新的 valvar,因此效率也更高。谢谢om-nom-nom
    • 可能想要将parseArguments(args,"") 编辑为parseArguments(args.toList,"") 无法在 2.9.2 中编译,因为这种转换似乎不是隐式的。
    • @korefn 是的,我有这个想法,但在我编写代码时不知何故错过了它。
    猜你喜欢
    • 2011-01-18
    • 2010-11-03
    • 2015-08-31
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多