web-dev-qa-db-ja.com

指定された引数を受け入れる '/'のオーバーロードが見つかりませんでした

// Playground - noun: a place where people can play


func getAverage(numbers: Int...) -> Double{
    var total = 0
    var average:Double = 0

    for number in numbers{
        total = total + number
    }

    average = total / numbers.count

    return average
}

getAverage(3, 6)

average = total / numbers.countでエラーが表示されます

指定された引数を受け入れる '/'のオーバーロードが見つかりませんでした

私は次のようにして修正しようとしました:

average = Double(total/numbers.count)

しかし、その後getAverageは4ではなく4.5に設定されました

36
Arian Faurtosh

Swiftにはそのような暗黙の変換はないため、それを自分で明示的に変換する必要があります。

_average = Double(total) / Double(numbers.count)
_

From The Swift Programming Language =:「値が暗黙的に別の型に変換されることはありません。」(セクション:A Swift Tour)

しかし、Objective-CではなくSwiftを使用しているので、より機能指向の方法で考えてみてください。関数は次のように記述できます。

_func getAverage(numbers: Int...) -> Double {
    let total = numbers.reduce(0, combine: {$0 + $1})
    return Double(total) / Double(numbers.count)
}
_

reduceは、アキュムレーター変数の初期値として最初のパラメーターを取得し、アキュムレーター変数と配列内の各要素にcombine関数を適用します。ここでは、_$0_および_$1_を使用して、渡される最初と2番目のパラメーターを示す匿名関数を渡し、それらを加算します。

さらに簡潔に、これを書くことができます:numbers.reduce(0, +)

型推論が、totalIntであることをまだ発見するという素晴らしい仕事をしていることに注意してください。

62

コンパイラーは、入力パラメーターと出力パラメーターに基づいて_/_演算子の実装を選択します。あなたの場合、入力パラメーターは2つのInt値で、出力パラメーターはDoubleです。これはコンパイラが探しているものです:

_func / (left: Int, right: Int) -> Double
_

ただし、_/_演算子のそのような実装はないため、エラーが発生します。 Double(total/numbers.count)を実行すると、出力パラメーターがIntに変わります。これが、コンパイラーが存在する_/_演算子の次の実装を選択する理由です。

_func / (left: Int, right: Int) -> Int
_

これが、結果をDoubleに変換した後でも、結果として_4_ではなく_4.5_を取得する理由です。

(独自の実装 _/_演算子を提供できます。これは、最初に数値をDoublesに変換します。

_func / (left: Int, right: Int) -> Double {
    return Double(left) / Double(right)
}
_

その後、次のことができます。

_let a: Int = 3
let b: Int = 2
let c: Double = a/b  // -> 1.5
_
6
Tom