2014-06-12 15 views
24

Nel Swift "Tour" documentation, c'è un esercizio in cui si costruisce il seguente funzione di media una serie di numeri:Perché non posso dividere gli interi in rapido?

func sumOf(numbers: Int...) -> Int { 
    var sum = 0 
    for number in numbers { 
     sum += number 
    } 
    return sum 
} 

posso fare questo lavoro utilizzando qualcosa di simile al seguente:

func averageOf(numbers: Double...) -> Double { 
    var sum: Double = 0, countOfNumbers: Double = 0 
    for number in numbers { 
     sum += number 
     countOfNumbers++ 
    } 
    var result: Double = sum/countOfNumbers 
    return result 
} 

La mia domanda è, perché devo lanciare tutto come un doppio per farlo funzionare? Se provo a lavorare con gli interi, in questo modo:

func averageOf(numbers: Int...) -> Double { 
    var sum = 0, countOfNumbers = 0 
    for number in numbers { 
     sum += number 
     countOfNumbers++ 
    } 
    var result: Double = sum/countOfNumbers 
    return result 
} 

ottengo il seguente errore: Could not find an overload for '/' that accepts the supplied arguments

+0

'var result: Double = Double (sum)/Double (countOfNumbers)', oppure è possibile sovraccaricare l'operatore, se lo si desidera. – holex

+1

Quale risultato ti aspetti? Il cast medio troncato come doppio, o la media come se gli inte fossero doppi? (Vale a dire [4,3] restituire 3,5 (7,0/2) o 3 (7/2)?) –

+0

Dovresti sapere che devi RTFM per qualcosa di banale come la divisione di interi. – Pescolly

risposta

29

Il PO sembra sapere come il codice deve essere simile ma lui sta chiedendo esplicitamente perché non lo è lavorando dall'altra parte

Quindi, "in modo esplicito" fa parte della risposta che sta cercando: Apple scrive all'interno del "Language Guide" nel capitolo "Le basi" -> "interi e virgola mobile di conversione":

Conversions between integer and floating-point numeric types must be made explicit

+0

sì, grazie è esattamente quello che sto cercando. Intuitivamente, mi aspetterei che se lancio il risultato (variabile _or_ return value) come Double, ho detto al compilatore cosa fare. Non ho ancora letto così tanto nella guida linguistica, quindi non lo sapevo. –

14

solo bisogno di fare questo:

func averageOf(numbers: Int...) -> Double { 
    var sum = 0, countOfNumbers = 0 
    for number in numbers { 
     sum += number 
     countOfNumbers++ 
    } 
    var result: Double = Double(sum)/Double(countOfNumbers) 
    return result 
} 
+2

che è ancora un'implementazione errata. – holex

+0

scusate, risolto :) –

3

che può essere helful:

func averageOf(numbers: Int...) -> Double { 
    var sum = 0, countOfNumbers = 0 
    for number in numbers { 
     sum += number 
     countOfNumbers++ 
    } 
    var result: Double = Double(sum)/Double(countOfNumbers) 
    return result 
} 

O

sovraccaricare l'operatore / per Int valori può essere anche una soluzione:

func/(lhs: Int, rhs: Int) -> Double { 
    return Double(lhs)/Double(rhs) 
} 
10

si sta assegnando l'output di / ad una variabile di tipo Double, in modo da Swift pensa che si desidera chiamare questa funzione:

func /(lhs: Double, rhs: Double) -> Double 

Ma gli argomenti che stai passando non sono Double s e Swift non fa cast implicito g.

+0

Grazie, anche questo aiuta, non mi sono reso conto che "/" era in realtà solo una funzione regolare. –

+0

Questo è stato un vero aha per me e potrebbe essere la migliore risposta./è una funzione che accetta 2 argomenti che devono essere entrambi doppi. Spiega la necessità di eseguire il cast prima di eseguire la divisione e spiega il messaggio di errore che produce xcode. – jamesrward

1

Prova questo, ma notare che a swift non piace dividere per interi che sono inizializzati a zero o potrebbero diventare zero, quindi devi usare &/per forzare la divisione. questo codice è un po 'prolisso, ma è facile da capire e dà la risposta corretta in interi punto non mobile o doppia

func sumOf(numbers: Int...) -> Int { 
var sum = 0 
var i = 0 
var avg = 1 
for number in numbers { 
    sum += number 
    i += 1 
} 
avg = sum &/ i 
return avg 
} 
sumOf() 
sumOf(42, 597, 12) 
1

Non c'è alcun motivo per tenere traccia manualmente il numero di argomenti quando si può semplicemente ottenere direttamente .

func sumOf(numbers: Int...) -> Int { 
    var sum = 0 
    for number in numbers { 
     sum += number 
    } 
    let average = sum &/ numbers.count 
    return average 
} 

sumOf() 
sumOf(42, 597, 12) 
0

Non trovo una necessità per una divisione forzata. L'operatore di divisione normale funziona comunque. Nel seguente codice,

func average(numbers:Int...)->Float{ 
    var sum = 0 
    for number in numbers{ 
     sum += number 
    } 
    var average: Float = 0 
    average = (Float (sum)/Float(numbers.count)) 
    return average 
} 
let averageResult = average(20,10,30) 
averageResult 

Qui, due valori float sono divisi, naturalmente dopo tipo casting sto memorizzando il risultato in una variabile float e restituzione della stessa.

Nota: Non ho usato una variabile extra per contare il numero di parametri. "numeri" sono considerati come array, poiché le funzioni in Swift prendono un numero variabile di argomenti in una matrice. "numbers.count" (Simile all'obiettivo C) restituirà il conteggio dei parametri passati.

Problemi correlati