[swift] Swift에서 가변 개수의 인수를 가진 함수에 배열 전달

에서 스위프트 프로그래밍 언어 , 그것은 말합니다 :

함수는 가변 개수의 인수를 가져 와서 배열로 수집 할 수도 있습니다.

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

쉼표로 구분 된 숫자 목록 (`sumOf (1, 2, 3, 4)으로 이러한 함수를 호출하면 함수 내부에서 배열로 사용할 수 있습니다.

질문 :이 함수에 전달할 숫자 배열이 이미 있으면 어떻게합니까?

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

“제공된 인수를 허용하는 ‘__conversion’에 대한 과부하를 찾을 수 없습니다.”라는 컴파일러 오류와 함께 실패합니다. 기존 배열을 가변성 함수에 전달할 수있는 요소 목록으로 바꾸는 방법이 있습니까?



답변

개발자들이 확인한 바에 따르면 튀어 오르는 언어는 아직 없습니다 . 현재 해결 방법은 과부하를 사용하거나 과부하를 추가 할 수없는 경우 기다리는 것입니다.


답변

내가 찾은 해결 방법이 있습니다. 나는 그것이 당신이 원하는 것이 아니라는 것을 알고 있지만 작동하는 것 같습니다.

1 단계 : 가변 인수 대신 배열을 사용하여 원하는 함수를 선언하십시오.

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

2 단계 : 가변 함수 내에서이를 호출하십시오.

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

3 단계 : 어느 쪽이든 전화하십시오.

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

이상하게 보이지만 테스트에서 작동합니다. 이것이 누군가에게 예기치 않은 문제를 일으키는 지 알려주십시오. Swift는 동일한 함수 이름으로 두 호출의 차이점을 분리 할 수있는 것으로 보입니다.

또한이 방법을 사용하면 @manojid의 답변에서 알 수 있듯이 Apple이 언어를 업데이트하면 이러한 기능 만 업데이트하면됩니다. 그렇지 않으면 많은 변경 작업을 거쳐야합니다.


답변

함수를 캐스트 할 수 있습니다.

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


답변

다음과 같은 도우미 기능을 사용할 수 있습니다.

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


답변

이 답변이 귀하의 정확한 질문에 대한 답변이 아니라는 점을 알고 있습니다. 나도 스위프트와 놀기 시작했고 즉시 비슷한 질문에 부딪쳤다. Manojlds 답변은 귀하의 질문에 더 좋습니다. 동의하지만 다시 한 번 다른 해결책이 있습니다. 나는 로건을 더 좋아한다.

내 경우에는 방금 배열을 전달하고 싶었습니다.

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])

다른 사람이 나처럼 생각하는 경우를 대비하여 공유하고 싶었습니다. 대부분 이런 식으로 배열을 전달하는 것을 선호하지만 “Swiftly”는 아직 생각하지 않습니다. 🙂


답변

나는 이것을했다 (Wrapper + Identity Mapping) :

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

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


답변

스위프트 5

이것은 @dynamicCallable과부하를 피할 수 있는 기능을 갖춘 접근법 unsafeBitCast이지만 struct전화를 구체적으로 해야합니다.

@dynamicCallable
struct SumOf {
    func dynamicallyCall(withArguments args: [Int]) -> Int {
        return args.reduce(0, +)
    }
}

let sum = SumOf()

// Use a dynamic method call.
sum(1, 2, 3) // 6

// Call the underlying method directly.
sum.dynamicallyCall(withArguments: [1, 2, 3]) // 6