繁体   English   中英

关于Swift函数,命名参数和类型管理

[英]About Swift functions, named parameters, and type management

假设我有一个这样的函数重载:

func doMath(mathOption: String) -> (Int...) -> Double {
    ...
    return average
}

func doMath(mathOption: String) -> ([Int]) -> Double {
    ...
    return average
}

旁注:函数average本身已过载,可以接受数组作为输入或参数列表。

两个问题:

1-如何引用我要指的功能?

例如:

let doAverage = doMath(mathOption: "average")

如何指定要调用的doMath函数? Swift很困惑,无法从下一行推断出来:

如果以后再写:

doAverage(1,2,3,4)

2-如何命名参数? 原始的平均函数因此被称为:

average(nums: 1,2,3,4)

我必须命名参数。 但是使用doAverage时,由于返回类型的定义方式,我无法命名参数。

3-如何创建类型(也许使用struct?)来简化此假设代码。

感谢您提供的任何帮助,解释或答案!


编辑,以澄清3,这是情况的扩展版本:

func sumAll(nums: [Int]) -> Double {
    return Double(nums.reduce(0, { (a,b) in a+b}))
}

func sumAll(nums: Int...) -> Double {
    return sumAll(nums: nums)
}


func average(nums: [Int]) -> Double {
    return sumAll(nums: nums) / Double(nums.count)
}

func average(nums: Int...) -> Double {
    return average(nums: nums)
}

func doMath(mathOption: String, nums: Int...) -> Double {
    if mathOption == "average" {
        return average(nums: nums)
    } else {
        return sumAll(nums: nums)
    }
}

typealias mathReturnType1 = (Int...) -> Double
typealias mathReturnType2 = ([Int]) -> Double


func doMath(mathOption: String) -> mathReturnType1 {
    return average
}

func doMath(mathOption: String) -> mathReturnType2 {
    return average
}

我使用typealias创建了两个示例类型。 是否可以以某种方式重载类型以处理两种情况? 对我来说,这是有意义的,如果要重载相同的函数以处理不同的输入,那为什么不选择类型呢? 也许这是一个幼稚的观点,或者也许有一种方法可以表达我在Swift中的想法?

如何引用功能? 只需指定类型!

func doMath(mathOption: String) -> (Int...) -> Double {
    return { (values: Int...) -> Double in
        return Double(values.reduce(0, +)) / Double(values.count)
    }
}

func doMath(mathOption: String) -> ([Int]) -> Double {
    return { (values: [Int]) -> Double in
        return Double(values.reduce(0, +)) / Double(values.count)
    }
}

let average1 = doMath(mathOption: "x") as (Int...) -> Double
print(average1(1, 2, 3))

要么

let average1: (Int...) -> Double = doMath(mathOption: "x")
print(average1(1, 2, 3))

我还建议使用typealias命名该类型。

第二个问题-您不能在函数类型中命名参数。

您可以将要完成的功能作为参数传递给doMath。 并使用泛型,因此您具有一定的可扩展性。

func doMath<T>(using op: (T) -> Double, with value: T) -> Double {

    return op(value)

}

doMath(using: sumAll, with: [1,2,3])
// returns 6

编辑:可变参数有麻烦。 另一个编辑:找到了一种解决方法。

func doMath<T>(using op: ([T]) -> Double, with value: T...) -> Double {

    return op(value)

}

func doMath<T>(using op: (T) -> Double, with value: T) -> Double {

    return op(value)

}

doMath(using: sumAll, with: 1,2,3,4,5)  //15
doMath(using: sumAll, with: [1,2,3,4,5]) // 15

另外,这是一种写得精简的方法,可以减少:

Double(nums.reduce(0, +))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM