func performMathAverage (mathFunc: String) -> ([Int]) -> Double {
switch mathFunc {
case "mean":
return mean
case "median":
return median
default:
return mode
}
}
我从一本快速学习的书中得到了这个例子,它讲述了返回函数类型的主题,这只是整个程序的一部分,我不想复制并粘贴它们。我的困惑是这本书说:
“注意在performMathAverage中,在switch案例中,我们返回 均值,中位数或模式,而不是mean(),median()或mode() 。这是因为我们没有调用方法,而是我们 返回对它的引用,就像C中的函数指针一样 实际调用该函数以获取添加括号的值 后缀为函数名称。也请注意,任何平均值 函数可以独立调用而不使用 performMathAverage函数。这是因为平均值,中位数和模式 被称为全局函数。“
主要问题是:“我们为什么不调用这些方法?” 它们是什么意思我们正在返回它的引用??
他们的意思是什么?我只是对这部分感到困惑。
答案 0 :(得分:3)
你说的主要问题是:
"为什么我们不调用这些方法?"它们是什么意思我们正在返回它的引用??
首先要抓住这个有点棘手,但是它说的是我们不想要函数的结果,我们想要函数本身。
有时这样的事情更容易理解w /类型别名:
从w [Int] -> Int
开始,我们所说的有一个"一个函数,它接受Int
个数组并返回一个Int
&#34 ;
为了清晰起见,我们制作一个类型别名:
typealias AverageFunction = [Int] -> Int
现在我们的函数(来自您的示例)如下所示:
func performMathAverage(mathFunc: String) -> AverageFunction {
虽然这里的命名惯例非常令人困惑,因为我们没有执行任何操作,而是让我们这样称呼它:
func getAverageFunctionWithIdentifier(identifier: String) -> AverageFunction {
现在很清楚,这种方法的功能就像工厂一样,根据我们提供的标识符返回平均功能。现在让我们来看看实现:
func getAverageFunctionWithIdentifier(identifier: String) -> AverageFunction {
switch identifier {
case "mean":
return mean
case "median":
return median
default:
return mode
}
}
现在,我们在标识符上运行一个开关来查找相应的功能。同样,我们没有调用该函数,因为我们不想要该值,我们想要函数本身。让我们来看看我们如何称呼它:
let averageFunction = getAverageFunctionWithIdentifier("mean")
现在,averageFunction
是平均函数的引用,这意味着我们可以使用它来获取整数数组的均值:
let mean = averageFunction([1,2,3,4,5])
但是如果我们想要使用不同类型的平均值,比如说中位数呢?除标识符外,我们不必更改任何内容:
let averageFunction = getAverageFunctionWithIdentifier("median")
let median = averageFunction([1,2,3,4,5])
这个例子非常有用,但这样做的好处是通过将函数抽象出它的类型(在这种情况下为[Int] -> Int
),我们可以使用任何符合该类型的函数。
这是功能性编程!
答案 1 :(得分:1)
这与swift的functional programming方面有关。这里的函数被视为first class citizens,这意味着您可以将它们视为变量。
为什么我们不调用方法?
您没有调用方法,因为您没有要应用的参数。该功能的要点是确定您想要使用的哪个功能。当然,函数的名称很糟糕,并不能准确地表示函数的功能。它应该更像func determineMathFuncToUse
,然后就可以像
var myFunc = determineMathFuncToUse("median")
// Now, you would be able to use myFunc just like you would use median
// e.g. myFunc(some_array) == median(some_array)
答案 2 :(得分:1)
这很容易理解。在Swift中,您可以存储对函数的引用(您在Objective-C中可以实现的最接近的是对块的引用)。
func performMathAverage (mathFunc: String) -> ([Int]) -> Double
这是返回类型为的函数:
([Int]) -> Double
正如您所看到的,此函数的返回类型是一个接受Int
数组并返回Double
的函数。
在代码中,您会看到它返回三个函数之一:mean
,mode
和median
。这些函数中的每一个都接受Int
的数组并返回Double
。
由于以下代码:
let meanFunc = performMathAverage("mean")
let mean = meanFunc(someIntArray)
与:
相同let mean = mean(someIntArray)
我希望这会有所帮助。
函数未在代码中执行的原因是因为此示例说明了如何存储对函数的引用。
可能很难理解为什么你会想要在这种特殊情况下这样做,但是,嘿,打印“Hello world”似乎也毫无意义:)
你指的是教程中的一个例子,所以它们过于简单化并不奇怪。但是,相信我,在现实世界中,存在很多情况,其中存储对函数的引用是非常有用的!
一个明显的例子是当你想存储一些你想在一些冗长的操作结束时执行的完成处理程序的引用时。根据您启动此操作的上下文,它可能会有所不同。
答案 3 :(得分:0)
要回答你的问题,你实际上是在返回函数本身,而不是调用该函数的结果。在这种情况下,它允许您选择一个函数(使用switch语句)并在以后进行评估。考虑它的一个有用的方法是函数也是一种变量,你可以传递它们并评估它们。
作为一般风格,最好使用case
结束每个break
。这没有区别,因为return
也将结束函数的执行,但没有中断,所有代码在之后将执行正确的case
,而不仅仅是代码 正确的case
。运行到另一个case
语句本身并不会脱离switch语句。
答案 4 :(得分:0)
为什么我们不调用这些方法?
据推测,该方法将在稍后调用。 switch语句的目的是返回一个可以在以后使用的函数。
他们是什么意思我们正在回复它的引用? ......他们的意思是什么?
"参考"语言有点令人困惑 - 函数是引用类型,但这对于正在发生的事情并不是非常重要。你可以把它想象成只返回一个函数。
底线是swift中的函数可以像任何其他类型一样使用 - 它们可以存储在变量或常量中,它们可以作为参数传递给函数,并且它们可以从函数返回。
在这种情况下,您有一个旨在返回函数的函数。如果你想获得均值,你传递字符串" mean"并且该函数将返回一个新函数,当您调用它时将获得该函数。