ChatGPT解决这个技术问题 Extra ChatGPT

在 Swift 中将数组传递给具有可变数量参数的函数

The Swift Programming Language 中,它说:

函数还可以采用可变数量的参数,将它们收集到一个数组中。 func sumOf(numbers: Int...) -> Int { ... }

当我使用逗号分隔的数字列表 (`sumOf(1, 2, 3, 4) 调用这样的函数时,它们在函数内作为数组可用。

问题:如果我已经有一个要传递给此函数的数字数组怎么办?

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

这将失败并出现编译器错误,“找不到接受提供的参数的 '__conversion' 的重载”。有没有办法将现有数组转换为可以传递给可变参数函数的元素列表?

为什么不直接将函数配置为采用整数数组呢?
当然可以,但我可能不是该函数的作者,并且可能无法(或不想)更改它。
Ach @OleBegemann 我在这里,无法更改功能并阅读您的问题......现在仍然是解决方案......问候柏林

H
Hasaan Ali

Splatting is not in the language yet,正如开发人员所确认的那样。目前的解决方法是使用重载,或者如果您无法添加重载,则等待。


语言中的 Splatting 了吗?我正在尝试拨打 sumOf(...numbers)
太令人失望了!即使尝试将我自己的日志调用委托给print这样简单的事情,我也能做到这一点!
L
Logan

这是我发现的解决方法。我知道这不完全是你想要的,但它似乎正在工作。

第 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 似乎能够区分具有相同函数名称的两个调用之间的差异。

此外,如果Apple按照@manojid的回答建议更新语言,则使用此方法,您只需要更新这些功能。否则,您将不得不进行大量重命名。


谢谢,我喜欢解决方法。我仍然会向 manojlds 授予“正确”答案,因为它找到了官方确认该功能尚不可用的链接。我希望你明白。
您可能正在遵循指南,并且您的 func sumOf(numbers: [Int]) -> Int 实际上是在计算平均值
G
Guoye Zhang

您可以转换函数:

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

伟大的!这也适用于多个(命名)参数;例如:func sumOf(foo numbers: Int..., bar: Bool) -> Int {}; 需要 typealias Function = (foo: [Int], bar: Bool) -> Int;
伟大的!救我的命。
我怎样才能用 AnyObject... 做类似的事情? stackoverflow.com/questions/42016358/… 谢谢。
这是一个非常糟糕的主意。绝对零保证这会奏效。
@MattMc 当然。据我所知,没有什么可以让您使用 unsafeBitCast 简单地将一种可调用类型转换为另一种。这在今天可能有效,但除非参考说明如此,否则下一版本的编译器可以在这里自由地做任何事情(编译器错误/崩溃/随机执行代码......)。查看 unsafeBitCast 上看起来很严肃的警告。
G
GoZoner

您可以像这样使用辅助函数:

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

如果有数组的版本。我认为问题的前提是原始函数需要 Int... 并且不能(轻松)更改?
@delnan:正确。在我看来,应该有办法将数组传递给可变参数函数,因为可变参数参数无论如何都会变成数组。
在函数中接受可变数量参数的语言(如 Scheme)具有 apply 过程。我收集一些人称之为“喷溅”。
此处引用的 sumArray 是什么?
s
schirrmacher

我这样做了(包装器+身份映射):

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

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

g
gregthegeek

我知道这个回复没有回答你的确切问题,但我觉得它值得注意。我也开始使用 Swift 并立即遇到了类似的问题。我同意,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])

只是想分享一下,以防其他人像我一样思考。大多数时候我更喜欢像这样传递数组,但我不认为“迅速”。 :)


i
iUrii

斯威夫特 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

您还可以向 struct 添加另一种方法: func dynamicCall(withKeywordArguments args: KeyValuePairs) -> Int { let values = args.first?.value ?? [Int]() return values.reduce(0, +) } 然后您可以选择使用参数标签进行调用(任何方法都可以)。例如:总和(arr:[1,2,3])

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅