2016-09-02 9 views
0

私はすべてスピーディーなプログラミングの新人です。演算子の型である3つの引数と計算されるべき2つの数値に基づいて簡単な数式の計算を解決する関数を作成しようとしました。今私はそれがコードは次のようになりますここで私は満足しています限り、仕事に行った時間が経過した後:オペレータの議論(スウィフト)

func calculation(operatorType: String, number1: Double, number2: Double) -> Double { 

if operatorType == "+" { 
    return number1 + number2 

} else if operatorType == "-" { 
    return number1 - number2 

} else if operatorType == "/" { 
    return number1/number2 

} else if operatorType == "*" { 
    return number1 * number2 

} else { 
    return 0 
} 
} 

私が言ったように、それはかなりうまく動作します。私はそれがString型であるので、引用符でoperatorTypeを入れなければなりません、私は何も成功せずにそれらを取り除こうとしました。

しかし、今の点に:

私はコードが少し単純作ってみました、私が考えていた:全体が一つのコードで「引数と同じ演算子を使用」を挿入することは可能でしょうか?私は次のように試しました:

if operatorType == "*" || operatorType == "-".... 
return number1 + operatorType + number2 

正しい方程式にしますが、成功しません。だから私の質問は本当に、私は正しい考えている、そうすることが可能です、その場合、どのように?実際には基本的なコードであっても、少ないコードでより効率的な方法を使うのは良いことでしょう。

ありがとうございました!

編集: 名前があまり曖昧でない名前に変更されました。

答えて

0

Swiftには、文字列名で任意の関数(使用している演算子関数など)を取得するために必要なReflectionシステムがまだありません。あなたはswitchステートメントを使用して、コードを向上させることができます

func performOperation1(operatorName: String, _ operand1: Double, _ operand2: Double) -> Double { 
    switch (operatorName) { 
    case "+": return operand1 + operand2 
    case "-": return operand1 - operand2 
    case "*": return operand1 * operand2 
    case "/": return operand1/operand2 
    default: fatalError("Unsupported Operator Name") 
    } 
} 

operand1operand2を繰り返さないようにするには、クロージャ変数に演算子関数を格納し、そして最後に一度、それを呼び出すことができます。

func performOperation(operatorName: String, _ operand1: Double, _ operand2: Double) -> Double { 
    var f: (Double, Double) -> Double 

    switch (operatorName) { 
    case "+": f = (+) 
    case "-": f = (-) 
    case "*": f = (*) 
    case "/": f = (/) 
    default: fatalError("Unsupported Operator Name") 
    } 

    return f(operand1, operand2) 
} 
+1

ありがとうございました。私はまだswitch文を調べ始めていませんが、単純化してコードを一般的により効率的にする方法を見た後、明らかに私がしなければならないことです。私はそれを調べます、ありがとう! –

+0

スウィフトではスウィフトステートメントが素晴らしいです、**特に**です。私の回答があなたの質問を満たしていれば、マークは受け入れられた通りです。 – Alexander

1

あなたが選んだ例は、Higher-order Functions(HOM)を説明するための標準的な例です。

HOMは、別の関数(またはファンクタ)を入力として受け取り、これを使用してタスクを実行する関数です。
Swiftでは、それらを書き込む1つの方法は、クロージャをパラメータとして使用することです。

例では、関数は計算を切り替える文字列を使用せず、代わりにクロージャを使用します。
この単純なケースでは、関数は単にクロージャを実行して値を返します。

func calculate(op:((Int, Int)-> Int), operandA: Int, operandB: Int) -> Int { 
    return op(operandA, operandB) 
} 

あなたのオペレータの閉鎖は、あなたがこれは少し過度に洗練され、学術的に見えるかもしれません

let result = calculate(addition, operandA: 1, operandB: 3) 

のようにそれを実行するでしょう

let addition: ((Int, Int)-> Int) = { 
    return $0 + $1 
} 

または

let substruction: ((Int, Int)-> Int) = { 
    return $0 - $1 
} 

ようになります。しかし、アクチュアSwiftと一緒に使用する多くの方法がHOMです。例えば、mapおよびfilterである。彼らは一般的なので、少し進んでいますが、Intパラメータ以上のものを受け入れることができます。しかし、私はこのポストでそれをカバーしたくない...

+0

そのような場合、私は自分のコードで行ったStringsではなく、closureをパラメータとして使うべきですか?私は実際にこれを見ていないので、私はそれをやろうとして戻ってきて、それをうまく理解することを試みます。ありがとうございました! –

+0

@Antonödman質問の内容入力は演算子の文字列表現です。それが要件でない場合は、達成しようとしていることを正確に説明する新しい質問を投稿することをお勧めします。 – Alexander

+0

*私は自分のコードで行ったStringsの代わりにパラメータとしてclosureを使うべきですか?*その特定のケースでは、これらのソリューションを使用しないでください。 'let x = performOperation1(" + "、operand1:1、operand2:2)も' let x = calculate(addition、operandA:1、operandB2) 'のようなものでもない。ちょうど 'let x = 1 + 2' – vikingosegundo

関連する問題