Vraag Een array doorgeven aan een functie met een variabel aantal args in Swift


In De Swift programmeertaal, het zegt:

Functies kunnen ook een variabel aantal argumenten gebruiken om ze in een array te verzamelen.

  func sumOf(numbers: Int...) -> Int {
      ...
  }

Wanneer ik zo'n functie oproept met een door komma's gescheiden lijst met getallen (`sumOf (1, 2, 3, 4), worden ze beschikbaar gemaakt als een array binnen de functie.

Vraag: wat als ik al een reeks nummers heb die ik wil doorgeven aan deze functie?

let numbers = [1, 2, 3, 4]
sumOf(numbers)

Dit mislukt met een compileerfout: "Kon geen overbelasting vinden voor '__conversie' die de opgegeven argumenten accepteert". Is er een manier om een ​​bestaande array om te zetten in een lijst met elementen die ik kan doorgeven aan een variadische functie?


128
2018-06-03 20:29


oorsprong


antwoorden:


Splatting is nog niet in de taal, zoals bevestigd door de ontwikkelaars. Tijdelijke oplossing voor nu is om overbelasting te gebruiken of te wachten als u geen overbelasting kunt toevoegen.


80
2018-06-03 20:53



Hier is een werk dat ik heb gevonden. Ik weet dat het niet precies is wat je wilt, maar het lijkt te werken.

Stap 1: Verklaar de functie die u wilt met een array in plaats van variadische argumenten:

func sumOf(numbers: [Int]) -> Int {
    var total = 0
    for i in numbers {
        total += i
    }
    return total
}

Stap 2: Noem dit vanuit je variadische functie:

func sumOf(numbers: Int...) -> Int {
    return sumOf(numbers)
}

Stap 3: Bel in beide richtingen:

var variadicSum = sumOf(1, 2, 3, 4, 5)
var arraySum = sumOf([1, 2, 3, 4, 5])

Het lijkt vreemd, maar het werkt in mijn tests. Laat me weten of dit voor iemand onvoorziene problemen veroorzaakt. Swift lijkt in staat om het verschil tussen de twee oproepen met dezelfde functienaam te scheiden.

Met deze methode, als Apple de taal bijwerkt zoals het antwoord van @ manojid suggereert, hoeft u deze functies alleen maar bij te werken. Anders moet u doorgaan en veel hernoemen.


56
2018-06-03 20:54



Je kunt de functie casten:

typealias Function = [Int] -> Int
let sumOfArray = unsafeBitCast(sumOf, Function.self)
sumOfArray([1, 2, 3])

13
2018-01-01 13:11



U kunt een helperfunctie als zodanig gebruiken:

func sumOf (numbers : [Int])  -> Int { return numbers.reduce(0, combine: +) }
func sumOf (numbers : Int...) -> Int { return sumArray (numbers) }

11
2018-06-03 20:32



Ik deed dit (Wrapper + Identity Mapping):

func addBarButtonItems(types: REWEBarButtonItemType...) {
    addBarButtonItems(types: types.map { $0 })
}

func addBarButtonItems(types: [REWEBarButtonItemType]) {
    // actual implementation
}

1
2017-11-09 10:03



Ik weet dat deze reactie je exacte vraag niet beantwoordt, maar ik voel het vermelden waard. Ook ik begon met Swift te spelen en kwam meteen een soortgelijke vraag tegen. Manojlds antwoord is beter voor je vraag, ik ben het ermee eens, maar nogmaals, een andere oplossing die ik bedacht. Ik ben toevallig ook dol op Logan.

In mijn geval wilde ik gewoon een array doorgeven:

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

var someNums = [8,7,2,9,12]
sumOf(someNums)
sumOf([10, 15, 20])

Ik wilde het gewoon delen, voor het geval iemand anders dacht zoals ik. Meestal geef ik er de voorkeur aan de reeks op deze manier door te geven, maar ik denk nog niet dat het "snel" is. :)


0
2018-06-15 03:22