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

时间:2016-11-21 08:15:07

标签: swift function swift3

假设我有一个如此重载的函数:

angular.module('starter', ['ionic','ngCordova'])

.controller('MainController', ['Camera', function($scope, Camera){
    $scope.getPicture = function(options){
        var options = {
            quality : 75,
            targetWidth : 200,
            targetHeight : 200,
            sourceType : 0
        };

        Camera.getPicture(options).then(function(imageData){
            $scope.picture = imageData;
        }, function(err){
            console.log(err);
        });
    };

    $scope.takePicture = function(options){
        var options = {
            quality : 75,
            targetWidth: 200,
            targetHeight: 200,
            sourceType: 1
        };
        Camera.getPicture(options).then(function(imageData){
            $scope.picture = imageData;
        }, function(err){
            console.log(err);
        });
    }
}])

.factory('Camera', function($q){
        return {
          getPicture: function(options) {
             var q = $q.defer();

             navigator.camera.getPicture(function(result) {
                q.resolve(result);
             }, function(err) {
                q.reject(err);
             }, options);

             return q.promise;
          }
       }
    })

附注:函数func doMath(mathOption: String) -> (Int...) -> Double { ... return average } func doMath(mathOption: String) -> ([Int]) -> Double { ... return average } 本身被重载以接受数组作为输入或参数列表。

两个问题:

1 - 我如何参考我所指的功能?

例如:

average

如何指定我正在调用哪个doMath函数? Swift很困惑,不能从下一行推断:

如果我稍后写:

let doAverage = doMath(mathOption: "average")

2 - 如何命名参数?因此调用原始平均函数:

doAverage(1,2,3,4)

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

3 - 我如何创建一个类型(可能使用struct?)来简化这个假设代码。

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

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

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

我使用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 } 创建了两个示例类型。一个类型可以以某种方式超载以处理这两种情况吗?对我来说,这是有道理的,如果相同的函数被重载以处理不同的输入,为什么不是类型?也许这是一个天真的观点,或者也许有一种方式来表达我在Swift中的想法?

2 个答案:

答案 0 :(得分:0)

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

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来命名该类型。

您的第二个问题 - 您无法在函数类型中命名参数。

答案 1 :(得分:0)

您可以将您想要的功能传递给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, +))