Podczas pisania funkcji ogólnej czasami łatwiej jest podejść do niej w 3 krokach: najpierw napisz kod autonomiczny, używając określonego typu. Następnie wpisz kod jako funkcję, nadal z określonym typem. Na koniec zmień funkcję na ogólną.
Pierwsza część podzielenie tablicę przez 3 może być wykonane w następujący sposób:
let a = [1,2,3,4,5]
// map is run on the array of integers, and returns a new
// array with the operation performed on each element in a:
let b = a.map { $0/3 }
// so b will be [0,0,1,1,1]
// (don’t forget, integer division truncates)
Uwaga zamknięcie podać pomiędzy { }
to operacja, która zostanie przyłożona do każdej elementu tablicy . $0
reprezentuje element, a dzielisz go przez 3. Można również napisać go jako a.map { i in i/3 }
.
Aby umieścić to na własnej funkcji:
func divideby3Map(source: [Int]) -> [Int] {
return source.map { $0/3 }
}
Nie trzeba zadeklarować nową tablicę - map
stworzy dla Ciebie. Możesz wtedy zwrócić to bezpośrednio (możesz przypisać go do tymczasowego, jeśli chcesz, ale to nie jest konieczne).
Wreszcie, jeśli chcemy, aby było rodzajowe, start dodając zastępczy:
func divideby3Map<T>(source: [T]) -> [T] {
return source.map { $0/3 }
}
Uwaga, istnieje tylko potrzeba jednego zastępczego, T
, bo wracają dokładnie ten sam typ jesteś przekazany w
... Poza tym nie będzie kompilować, ponieważ kompilator nie wie, że T
gwarantuje dostarczenie dwóch ważnych rzeczy:. zdolność do podziału (operator /
) oraz zdolność do tworzenia nowych T
od liczby całkowitej literały (tj. stworzyć T
o wartości 3
, aby podzielić według). W przeciwnym razie, jeśli przekażemy tablicę łańcuchów lub tablicę tablic?
Aby to zrobić, musimy "ograniczyć" T
, więc nasza funkcja będzie akceptować tylko te typy argumentów, które zapewniają te funkcje. Jeden taki protokół możemy użyć, aby ograniczyć T
jest IntegerType
, który ma zagwarantować te funkcje (jak również kilka innych te, jak +
, *
etc):
func divideby3Map<T: IntegerType>(source: [T]) -> [T] {
return source.map { $0/3 }
}
divideby3Map(a) // returns [0,0,1,1,1]
let smallInts: [UInt8] = [3,6,9]
divideby3Map(smallInts) // returns [1,2,3]
Jeśli to tylko matematyka dlaczego nie można po prostu użyć Int lub Double? –